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

114 阅读5分钟

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. 关键组件协作流程

  1. HandlerMapping:将请求映射到处理器(Controller)
  2. HandlerAdapter:实际执行处理器方法
  3. ViewResolver:解析逻辑视图名到实际视图
  4. 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) {        // 返回值处理逻辑...    }}

四、关键设计模式应用

  1. 前端控制器模式:DispatcherServlet 作为单一入口
  2. 策略模式:HandlerMapping、HandlerAdapter 等组件可插拔
  3. 适配器模式:HandlerAdapter 统一不同处理器的调用方式
  4. 模板方法模式:处理流程在父类中定义,子类可扩展特定步骤
  5. 工厂模式:组件初始化和创建

五、性能优化关键点

  1. HandlerMapping 缓存:将URL到处理器的映射关系缓存
  2. 参数解析优化:避免每次请求都解析方法参数
  3. 视图解析缓存:缓存已解析的视图实例
  4. 并发控制:确保核心组件线程安全
  5. 懒加载:非必要组件延迟初始化

六、扩展点设计

  1. 自定义参数解析器:实现特定类型的参数自动装配
  2. 自定义返回值处理器:支持新的响应格式
  3. 拦截器链:实现AOP式横切关注点
  4. 异常处理机制:统一异常处理接口
  5. 主题解析:支持动态视图样式切换

总结

深入理解DispatcherServlet的处理流程和Spring MVC的设计原理,不仅能够帮助我们更好地使用框架,还能指导我们设计出结构清晰、扩展性强的Web框架。通过手写简化版MVC框架,可以更深刻地领会到Spring MVC中各个组件的职责划分和协作方式,以及各种设计模式在框架中的应用。这种理解对于解决复杂Web开发中的各种问题,以及进行框架定制和扩展都具有重要价值。