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开发中的各种问题,以及进行框架定制和扩展都具有重要价值。