专业编程教程与实战项目分享平台

网站首页 > 技术文章 正文

SpringMVC源码分析(springmvc开源项目源码)

ins518 2025-03-20 15:32:08 技术文章 16 ℃ 0 评论

我们来深入源码分析 Spring MVC 的核心流程和关键组件。Spring MVC 是 Spring Framework 提供的用于构建 Web 应用程序的模块,它基于 MVC (Model-View-Controller) 设计模式,提供了强大的灵活性和可扩展性。

Spring MVC 核心组件概览

在深入源码之前,我们先回顾一下 Spring MVC 的核心组件及其职责,这有助于我们理解源码的脉络:

  1. DispatcherServlet (核心调度器):
  2. Spring MVC 的前端控制器,所有请求的入口。
  3. 接收所有 HTTP 请求,并根据配置将请求分发给不同的处理器。
  4. 负责整个 MVC 流程的协调和控制。
  5. HandlerMapping (处理器映射器):
  6. 负责根据请求的 URL 查找匹配的 Handler (处理器)。
  7. Spring MVC 提供了多种 HandlerMapping 实现,例如 RequestMappingHandlerMapping (基于 @RequestMapping 注解)、SimpleUrlHandlerMapping (基于 URL 模式配置) 等。
  8. HandlerAdapter (处理器适配器):
  9. 由于 Handler 可以是不同类型的对象 (例如实现了特定接口的 Bean、使用了注解的普通方法等),HandlerAdapter 负责适配不同类型的 Handler,使其能够被 DispatcherServlet 调用。
  10. Spring MVC 提供了多种 HandlerAdapter 实现,例如 RequestMappingHandlerAdapter (用于处理使用 @RequestMapping 注解的方法)、HttpRequestHandlerAdapter (用于处理实现了 HttpRequestHandler 接口的 Handler) 等。
  11. Handler (处理器):
  12. 实际处理请求的组件,通常是一个方法或一个实现了特定接口的类。
  13. 负责业务逻辑处理,并返回 ModelAndView 对象 (包含模型数据和视图信息)。
  14. 在 Spring MVC 中,Handler 通常是 Controller 类中的方法,使用 @RequestMapping 等注解进行标记。
  15. ModelAndView (模型和视图):
  16. 用于封装 Handler 处理结果的对象,包含了模型数据 (Model) 和视图信息 (View)。
  17. Model:用于传递给视图的数据,通常是一个 Map 结构。
  18. View:视图对象或视图名称,用于指示如何渲染响应。
  19. ViewResolver (视图解析器):
  20. 负责根据视图名称解析出具体的 View 对象。
  21. Spring MVC 提供了多种 ViewResolver 实现,例如 InternalResourceViewResolver (用于解析 JSP 视图)、ThymeleafViewResolver (用于解析 Thymeleaf 视图) 等。
  22. View (视图):
  23. 负责将模型数据渲染成最终的响应内容 (例如 HTML, JSON, XML 等)。
  24. Spring MVC 提供了多种 View 实现,例如 JstlView (用于渲染 JSP 视图)、MappingJackson2JsonView (用于渲染 JSON 视图) 等。
  25. Interceptor (拦截器):
  26. 用于在请求处理的不同阶段进行拦截和处理,例如请求预处理、后处理、完成处理等。
  27. 可以用于实现日志记录、权限验证、性能监控等功能。
  28. Spring MVC 提供了 HandlerInterceptor 接口,可以自定义拦截器。
  29. ExceptionResolver (异常解析器):
  30. 负责处理请求处理过程中发生的异常。
  31. 可以将异常映射到特定的视图,或者返回特定的错误响应。
  32. Spring MVC 提供了 HandlerExceptionResolver 接口,可以自定义异常解析器。

Spring MVC 请求处理流程 (源码分析)

我们从 DispatcherServlet 的 doDispatch() 方法开始,逐步分析 Spring MVC 的请求处理流程。doDispatch() 方法是 DispatcherServlet 的核心方法,负责处理每个请求。

以下是
DispatcherServlet.doDispatch() 方法的简化流程 (基于 Spring Framework 5.x 版本,不同版本可能略有差异):

java复制代码// org.springframework.web.servlet.DispatcherServlet.java

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    boolean multipartRequestParsed = false;
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

    try {
        ModelAndView mv = null;
        Exception dispatchException = null;

        try {
            processedRequest = checkMultipart(request); // 1. 处理 Multipart 请求 (文件上传)
            multipartRequestParsed = (processedRequest != request);

            // 2. 查找 HandlerExecutionChain (包含 Handler 和 Interceptors)
            mappedHandler = getHandler(processedRequest);
            if (mappedHandler == null) {
                noHandlerFound(processedRequest, response); // 没有找到 Handler
                return;
            }

            // 3. 获取 HandlerAdapter
            HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

            // 4. 处理 Handler 执行前的 Interceptors (preHandle)
            if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                return; // Interceptor 拦截,请求结束
            }

            // 5. 执行 Handler (调用 HandlerAdapter 的 handle 方法)
            mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

            // 6. 处理异步请求 (AsyncWebRequest)
            if (asyncManager.isConcurrentHandlingStarted()) {
                return; // 异步处理,请求交给 AsyncWebRequest 处理
            }

            applyDefaultViewName(processedRequest, mv); // 设置默认视图名

            // 7. 处理 Handler 执行后的 Interceptors (postHandle)
            mappedHandler.applyPostHandle(processedRequest, response, mv);
        }
        catch (Exception ex) {
            dispatchException = ex;
        }
        // 8. 处理异常 (Exception Resolution)
        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    }
    catch (Exception ex) {
        triggerAfterCompletion(processedRequest, response, mappedHandler, ex); // 处理 afterCompletion 异常
    }
    finally {
        if (asyncManager.isConcurrentHandlingStarted()) {
            // 异步请求完成时触发 afterCompletion
            if (mappedHandler != null) {
                mappedHandler.applyAfterCompletion(processedRequest, response, null);
            }
        }
        else {
            // 同步请求完成时触发 afterCompletion
            triggerAfterCompletion(processedRequest, response, mappedHandler, null);
        }
        if (multipartRequestParsed) {
            cleanupMultipart(processedRequest); // 清理 Multipart 请求资源
        }
    }
}

流程步骤详解和关键源码位置:

  1. 处理 Multipart 请求 (checkMultipart):
  2. DispatcherServlet.checkMultipart(HttpServletRequest request)
  3. 检查请求是否是 multipart/form-data 类型,如果是,则使用 MultipartResolver (例如 StandardServletMultipartResolver) 解析请求,将普通的 HttpServletRequest 包装成 MultipartHttpServletRequest,以便后续可以方便地获取上传的文件。
  4. 源码位置: org.springframework.web.servlet.DispatcherServlet.checkMultipart() 和 org.springframework.web.multipart.commons.CommonsMultipartResolver 或 org.springframework.web.multipart.support.StandardServletMultipartResolver
  5. 查找 HandlerExecutionChain (getHandler):
  6. DispatcherServlet.getHandler(HttpServletRequest request)
  7. 遍历配置的 HandlerMapping 列表,调用每个 HandlerMapping 的 getHandler() 方法,根据请求 URL 查找匹配的 Handler。
  8. HandlerMapping 返回的是 HandlerExecutionChain 对象,它包含了找到的 Handler 和一组应用于该 Handler 的 Interceptors。
  9. 源码位置: org.springframework.web.servlet.DispatcherServlet.getHandler() 和 org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler() 以及各种 HandlerMapping 实现类 (例如 RequestMappingHandlerMapping, SimpleUrlHandlerMapping)
  10. 获取 HandlerAdapter (getHandlerAdapter):
  11. DispatcherServlet.getHandlerAdapter(Object handler)
  12. 遍历配置的 HandlerAdapter 列表,找到能够处理当前 Handler 类型的 HandlerAdapter。
  13. 源码位置: org.springframework.web.servlet.DispatcherServlet.getHandlerAdapter() 和 org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter, org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter, org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter 等。
  14. 处理 Handler 执行前的 Interceptors (applyPreHandle):
  15. HandlerExecutionChain.applyPreHandle(HttpServletRequest request, HttpServletResponse response)
  16. 遍历 HandlerExecutionChain 中配置的 Interceptors,依次调用每个 Interceptor 的 preHandle() 方法。
  17. 如果任何一个 preHandle() 方法返回 false,则请求处理流程中断,直接返回。
  18. 源码位置: org.springframework.web.servlet.HandlerExecutionChain.applyPreHandle() 和 org.springframework.web.servlet.HandlerInterceptor.preHandle()
  19. 执行 Handler (ha.handle):
  20. HandlerAdapter.handle(HttpServletRequest request, HttpServletResponse response, Object handler)
  21. 调用选定的 HandlerAdapter 的 handle() 方法,执行实际的 Handler (Controller 方法)。
  22. HandlerAdapter 负责适配不同类型的 Handler,并将其调用统一为 ModelAndView 的返回。
  23. 例如,RequestMappingHandlerAdapter 会处理使用 @RequestMapping 注解的方法,并解析方法参数、调用方法、处理返回值等。
  24. 源码位置: 各种 HandlerAdapter 实现类的 handle() 方法,例如 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handle()
  25. 处理异步请求 (asyncManager.isConcurrentHandlingStarted()):
  26. Spring MVC 支持异步请求处理,如果 Handler 返回的是 Callable, DeferredResult 等异步类型,则会将请求交给 WebAsyncManager 进行异步处理。
  27. 源码位置: org.springframework.web.context.request.async.WebAsyncManager 和相关类。
  28. 处理 Handler 执行后的 Interceptors (applyPostHandle):
  29. HandlerExecutionChain.applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv)
  30. 遍历 HandlerExecutionChain 中配置的 Interceptors,逆序依次调用每个 Interceptor 的 postHandle() 方法。
  31. postHandle() 方法在 Handler 执行之后、视图渲染之前执行,可以对 ModelAndView 对象进行修改。
  32. 源码位置: org.springframework.web.servlet.HandlerExecutionChain.applyPostHandle() 和 org.springframework.web.servlet.HandlerInterceptor.postHandle()
  33. 处理异常 (processDispatchResult):
  34. DispatcherServlet.processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception ex)
  35. 如果在请求处理过程中发生异常 (dispatchException 不为 null),则调用 processHandlerException() 方法处理异常。
  36. 如果没有异常,则进行视图渲染 (render())。
  37. 源码位置: org.springframework.web.servlet.DispatcherServlet.processDispatchResult() 和 org.springframework.web.servlet.DispatcherServlet.processHandlerException() 以及 org.springframework.web.servlet.DispatcherServlet.render()
  38. 视图渲染 (render):
  39. DispatcherServlet.render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response)
  40. 如果 ModelAndView 对象不为空,则根据 ModelAndView 中的视图名称或 View 对象,使用 ViewResolver 解析视图,并调用 View 的 render() 方法进行视图渲染。
  41. 源码位置: org.springframework.web.servlet.DispatcherServlet.render() 和 org.springframework.web.servlet.ViewResolver.resolveViewName() 以及各种 View 实现类 (例如 JstlView, MappingJackson2JsonView) 的 render() 方法。
  42. 处理请求完成后的 Interceptors (triggerAfterCompletion):
  43. DispatcherServlet.triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, Exception ex)
  44. 遍历 HandlerExecutionChain 中配置的 Interceptors,逆序依次调用每个 Interceptor 的 afterCompletion() 方法。
  45. afterCompletion() 方法在整个请求处理完成之后 (包括视图渲染和异常处理) 执行,可以进行资源清理、日志记录等操作。
  46. 源码位置: org.springframework.web.servlet.DispatcherServlet.triggerAfterCompletion() 和 org.springframework.web.servlet.HandlerInterceptor.afterCompletion()

关键源码文件和目录:

  • org.springframework.web.servlet.DispatcherServlet.java: 核心调度器 DispatcherServlet 的实现。
  • org.springframework.web.servlet.HandlerMapping.java: HandlerMapping 接口定义。
  • org.springframework.web.servlet.HandlerAdapter.java: HandlerAdapter 接口定义。
  • org.springframework.web.servlet.ViewResolver.java: ViewResolver 接口定义。
  • org.springframework.web.servlet.View.java: View 接口定义。
  • org.springframework.web.servlet.HandlerInterceptor.java: HandlerInterceptor 接口定义。
  • org.springframework.web.servlet.HandlerExceptionResolver.java: HandlerExceptionResolver 接口定义。
  • org.springframework.web.servlet.mvc.method.annotation: 基于注解的 HandlerMapping 和 HandlerAdapter 实现 (例如 RequestMappingHandlerMapping, RequestMappingHandlerAdapter)。
  • org.springframework.web.servlet.view: 各种 ViewResolver 和 View 实现 (例如 InternalResourceViewResolver, JstlView, MappingJackson2JsonView)。
  • org.springframework.web.context.request.async: 异步请求处理相关的类。

总结:

Spring MVC 的源码分析是一个深入理解其工作原理的过程。通过分析
DispatcherServlet.doDispatch() 方法的流程,我们可以清晰地看到 Spring MVC 如何接收请求、查找 Handler、适配 Handler、执行 Handler、处理 Interceptors、解析视图、渲染视图以及处理异常。

学习建议:

  • 从 DispatcherServlet 入手: DispatcherServlet 是 Spring MVC 的核心,从 doDispatch() 方法开始跟踪请求处理流程是理解 Spring MVC 的关键。
  • 关注接口和抽象类: Spring MVC 中大量使用了接口和抽象类,例如 HandlerMapping, HandlerAdapter, ViewResolver, View, HandlerInterceptor, HandlerExceptionResolver 等。理解这些接口和抽象类的作用,有助于把握 Spring MVC 的扩展点和设计思想。
  • 结合调试工具: 使用 IDE 的调试功能,单步跟踪请求处理流程,观察变量的值和方法的调用,可以更直观地理解源码的执行过程。
  • 阅读官方文档和示例: Spring Framework 的官方文档和示例代码是学习源码的重要参考资料。
  • 逐步深入: Spring MVC 的源码比较庞大,可以先从核心流程入手,逐步深入到各个组件的细节实现。

希望这个 Spring MVC 源码分析能够帮助你更好地理解其内部机制。深入源码学习是一个持续的过程,需要耐心和实践。

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表