「完结20章」Java高手提薪精选——Spring源码解析到手写核心组件

dvdvo · · 272 次点击 · 开始浏览    置顶
这是一个创建于 的主题,其中的信息可能已经有所发展或是发生改变。

获课♥》789it.top/14681/ Spring MVC 源码深度解析:DispatcherServlet 处理流程与手写 MVC 框架的关键设计 一、DispatcherServlet 核心处理流程解析 Spring MVC 的核心控制器 DispatcherServlet 是整个框架的中枢神经,它负责协调各个组件完成请求处理的全过程。让我们深入分析其处理流程: 1. 请求处理主流程 DispatcherServlet 继承自 HttpServlet,其核心处理逻辑在 doDispatch() 方法中: java 复制 下载 protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { // 1. 获取已处理的请求(用于文件上传等场景) HttpServletRequest processedRequest = request; // 2. 获取处理器执行链 HandlerExecutionChain mappedHandler = null; // 3. 检查是否为文件上传请求 boolean multipartRequestParsed = false; // 4. 获取异步管理器 WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try { // 5. 实际请求处理 ModelAndView mv = null; Exception dispatchException = null; try { // 6. 检查文件上传请求 processedRequest = checkMultipart(request); multipartRequestParsed = (processedRequest != request); // 7. 确定处理器 mappedHandler = getHandler(processedRequest); if (mappedHandler == null) { noHandlerFound(processedRequest, response); return; } // 8. 获取处理器适配器 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler()); // 9. 处理Last-Modified头 String method = request.getMethod(); boolean isGet = "GET".equals(method); if (isGet || "HEAD".equals(method)) { long lastModified = ha.getLastModified(request, mappedHandler.getHandler()); if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } // 10. 执行拦截器preHandle if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // 11. 实际处理器调用 mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); // 12. 设置默认视图名 if (mv != null && !mv.hasView()) { mv.setViewName(getDefaultViewName(request)); } // 13. 执行拦截器postHandle mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } // 14. 处理分发结果 processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { // 异常处理 triggerAfterCompletion(processedRequest, response, mappedHandler, ex); }} 2. 关键组件协作流程 HandlerMapping:将请求映射到处理器(Controller) HandlerAdapter:实际执行处理器方法 ViewResolver:解析逻辑视图名到实际视图 HandlerInterceptor:拦截器实现预处理和后处理 二、核心组件设计与实现原理 1. HandlerMapping 实现机制 Spring MVC 提供了多种 HandlerMapping 实现: RequestMappingHandlerMapping:基于注解@RequestMapping BeanNameUrlHandlerMapping:基于Bean名称 SimpleUrlHandlerMapping:基于URL模式 java 复制 下载 // RequestMappingHandlerMapping 关键代码protected RequestMappingInfo createRequestMappingInfo( RequestMapping requestMapping, @Nullable RequestCondition<?> customCondition) { RequestMappingInfo.Builder builder = RequestMappingInfo .paths(resolveEmbeddedValuesInPatterns(requestMapping.path())) .methods(requestMapping.method()) .params(requestMapping.params()) .headers(requestMapping.headers()) .consumes(requestMapping.consumes()) .produces(requestMapping.produces()) .mappingName(requestMapping.name()); if (customCondition != null) { builder.customCondition(customCondition); } return builder.options(this.config).build();} 2. HandlerAdapter 适配器模式 HandlerAdapter 接口定义了处理器适配的标准: java 复制 下载 public interface HandlerAdapter { boolean supports(Object handler); ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception; long getLastModified(HttpServletRequest request, Object handler);} RequestMappingHandlerAdapter 是主要的实现类,它负责处理带有@RequestMapping注解的方法。 3. 参数解析与返回值处理 Spring MVC 通过 HandlerMethodArgumentResolver 和 HandlerMethodReturnValueHandler 实现灵活的参数解析和返回值处理: java 复制 下载 // 参数解析器接口public interface HandlerMethodArgumentResolver { boolean supportsParameter(MethodParameter parameter); Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception;}// 返回值处理器接口public interface HandlerMethodReturnValueHandler { boolean supportsReturnType(MethodParameter returnType); void handleReturnValue(Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception;} 三、手写简易MVC框架关键设计 基于对Spring MVC的理解,我们可以设计一个简易的MVC框架,以下是关键设计点: 1. 核心架构设计 java 复制 下载 // 框架核心类图+----------------+ +----------------+ +----------------+| Dispatcher |------>| HandlerMapping |------>| Handler |+----------------+ +----------------+ +----------------+ | ^ ^ v | |+----------------+ +----------------+ +----------------+| HandlerAdapter |<------| Controller | | @RequestMapping |+----------------+ +----------------+ +----------------+ | v+----------------+ +----------------+| ViewResolver |------>| View |+----------------+ +----------------+ 2. 核心实现代码 DispatcherServlet 简化版: java 复制 下载 public class MyDispatcherServlet extends HttpServlet { private List<HandlerMapping> handlerMappings; private List<HandlerAdapter> handlerAdapters; private List<ViewResolver> viewResolvers; @Override public void init() { // 初始化组件 initHandlerMappings(); initHandlerAdapters(); initViewResolvers(); } protected void doDispatch(HttpServletRequest req, HttpServletResponse resp) throws Exception { // 1. 获取处理器 Object handler = getHandler(req); if (handler == null) { resp.sendError(HttpServletResponse.SC_NOT_FOUND); return; } // 2. 获取处理器适配器 HandlerAdapter ha = getHandlerAdapter(handler); // 3. 执行处理器 ModelAndView mv = ha.handle(req, resp, handler); // 4. 渲染视图 processDispatchResult(req, resp, mv); } private void processDispatchResult(HttpServletRequest req, HttpServletResponse resp, ModelAndView mv) throws Exception { if (mv == null) return; View view = resolveViewName(mv.getViewName(), mv.getModel(), req); view.render(mv.getModel(), req, resp); } // 其他辅助方法...} 注解定义: java 复制 下载 @Target({ElementType.TYPE, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface MyRequestMapping { String value() default ""; RequestMethod[] method() default {};}@Target(ElementType.PARAMETER)@Retention(RetentionPolicy.RUNTIME)public @interface MyRequestParam { String value() default ""; boolean required() default true;} HandlerAdapter 实现: java 复制 下载 public class MyHandlerAdapter implements HandlerAdapter { @Override public boolean supports(Object handler) { return handler instanceof HandlerMethod; } @Override public ModelAndView handle(HttpServletRequest req, HttpServletResponse resp, Object handler) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; // 1. 准备参数 Object[] args = resolveArgs(handlerMethod, req, resp); // 2. 反射调用方法 Object result = handlerMethod.getMethod().invoke( handlerMethod.getBean(), args); // 3. 处理返回值 return handleResult(result, handlerMethod); } private Object[] resolveArgs(HandlerMethod handlerMethod, HttpServletRequest req, HttpServletResponse resp) { // 参数解析逻辑... } private ModelAndView handleResult(Object result, HandlerMethod handlerMethod) { // 返回值处理逻辑... }} 四、关键设计模式应用 前端控制器模式:DispatcherServlet 作为单一入口 策略模式:HandlerMapping、HandlerAdapter 等组件可插拔 适配器模式:HandlerAdapter 统一不同处理器的调用方式 模板方法模式:处理流程在父类中定义,子类可扩展特定步骤 工厂模式:组件初始化和创建 五、性能优化关键点 HandlerMapping 缓存:将URL到处理器的映射关系缓存 参数解析优化:避免每次请求都解析方法参数 视图解析缓存:缓存已解析的视图实例 并发控制:确保核心组件线程安全 懒加载:非必要组件延迟初始化 六、扩展点设计 自定义参数解析器:实现特定类型的参数自动装配 自定义返回值处理器:支持新的响应格式 拦截器链:实现AOP式横切关注点 异常处理机制:统一异常处理接口 主题解析:支持动态视图样式切换 总结 深入理解DispatcherServlet的处理流程和Spring MVC的设计原理,不仅能够帮助我们更好地使用框架,还能指导我们设计出结构清晰、扩展性强的Web框架。通过手写简化版MVC框架,可以更深刻地领会到Spring MVC中各个组件的职责划分和协作方式,以及各种设计模式在框架中的应用。这种理解对于解决复杂Web开发中的各种问题,以及进行框架定制和扩展都具有重要价值。

有疑问加站长微信联系(非本文作者)

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

272 次点击  
加入收藏 微博
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传