SpringMVC 执行流程

文章目录

    • 1. DispatcherServlet
    • 2. 处理器映射HandlerMapping
    • 3. 处理器Handler
    • 4. 处理器适配器HandlerAdapter
    • 5. 总结

SpringMVC 执行流程_第1张图片

类名 作用
Servlet 一个规范,用来解决 HTTP服务器和业务代码之间的耦合问题
GenericServlet 提升了 ServletConfig 的作用域,在init(servletConfig)方法中调用了init()无参方法,子类可以重写这个无参初始化方法来做一些初始化自定义工作(后面分析源码中会讲到)。
HttpServletBean 可以将 Servlet 配置信息作为 Bean 的属性 自动赋值给 Servlet 的属性。
FrameworkServlet 是 DispatcherServlet 的一个抽象父类。其中提供了加载某个对应的 web 应用程序环境的功能,还有将 GET、POST、DELETE、PUT等方法统一交给 DispatcherServlet 处理。
DispatcherServlet 整个继承链中的最后一个也是最重要的一个类,是SpringMVC 实现的核心类。MVC 通过在 web.xml 中配置 DispatcherServlet 来拦截所有请求,然后通过这个 DispatcherServlet 来进行请求的分发,并调用相应的处理器去处理请求和响应消息。

1. DispatcherServlet

DispatcherServlet 是HTTP请求处理程序/控制器的中央调度程序
正因为它是调度程序,所以就需要对请求的url需要进行处理。因此就需要处理器,以及url和处理器的映射关系。

简单来说
当DispatcherServlet接收到请求Request,遍历并根据处理器映射HandlerMapping,找到url对应的处理器Handler,
处理器调用处理方法返回结果Response

2. 处理器映射HandlerMapping

将请求与拦截器列表一起映射到处理程序,以进行预处理和后期处理。 映射基于某些条件,其细节因HandlerMapping实现而异。

HandlerMapping的两个主要实现是RequestMappingHandlerMapping(支持@RequestMapping带注释的方法)和SimpleUrlHandlerMapping(维护对处理程序的URI路径模式的显式注册)。

初始化
在 HttpServletBean 中重写了 GenericServlet 的 init() 无参方法开始初始化动作,其中HttpServletBean中先实现了 servlet 配置信息到 bean 属性信息的赋值,然后调用 initServletBean() 该方法是子类进行自定义初始化的方法。FrameworkServlet 实现了该方法并且调用了 initWebApplicationContext() 方法进行了容器和上下文的初始化工作,并且其中调用了 onRefresh(ApplicationContext context) 方法。 这里FrameworkServlet没有做任何操作而是子类 DispatcherServlet 在其中调用了 initStrategies(context) 进行初始化工作。

3. 处理器Handler

根据请求Request获取处理器Handler步骤

DispatcherServlet的doDispatcher方法处理请求request

doDispatcher方法中,根据请求request找到当前的处理器Handler

mappedHandler = getHandler(processedRequest);

HandlerMapping 会包装一个控制器的方法和对它的一些拦截器
getHandler方法中,遍历处理器映射Handlermapping,根据请求request,在处理器映射中找到处理器Handler

HandlerExecutionChain handler = mapping.getHandler(request);

mapping.getHandler方法中,真正的Handler获取是在子类实现的getHandlerInternal(request)中

Object handler = getHandlerInternal(request);

getHandlerInternal有多个子类,主要AbstractHandlerMethodMapping,AbstractUrlHandlerMapping
AbstractHandlerMethodMapping中实现的getHandlerInternal,会通过lookupHandlerMethod,根据路径找到最佳匹配的handlerMethod

HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);

HandlerMethod 中存放了控制器类和对应的方法,到时候调用处理方法只需要通过反射调用这个bean的method

4. 处理器适配器HandlerAdapter

帮助DispatcherServlet调用映射到请求的处理程序,而不管实际如何调用该处理程序。例如,调用带注释的控制器需要解析注释。HandlerAdapter的主要目的是保护DispatcherServlet这些细节。

在DispatcherServlet的doDispatcher方法中,找到当前的处理器Handler后,包装成处理器适配器HandlerAdapter

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

在调用 HandlerAdapter 的 处理方法的时候 会跳转调用到 RequestMappingHandlerAdapter 的 handleInternal 方法。这里面会将 原本的处理器 HandlerMethod 封装成 ServletInvocableHandlerMethod,然后会调用这个类中的 invokeAndHandle 方法,这个方法中主要进行了相应方法处理器的方法的调用,在调用之前,会将Http报文中的内容转换为对应的参数内容。在调用完成返回 returnValue 之后,会调用相应 HttpMessageConvert 的转换方法 然后返回。

5. 总结

当一个请求到来时,DispatcherServlet首先通过请求和事先解析好的HandlerMapping配置,找到对应的处理器Handler,
这样就准备开始运行处理器和拦截器组成的执行链,而运行处理器需要有一个对应的环境,获取一个处理的的适配器
HandlerAdapter,通过这个适配器就能运行对应的处理器及其拦截器,这里的处理器包含了控制器的内容和其他增强的功能,
在处理器返回模型和视图给DispatcherServlet后,会把对应的视图信息传递给视图解析器。这一步取决于是否使用逻辑视图,
是的话,视图解析器会解析它;不是的话,不会进行处理。最后响应用户的请求。

SpringMVC 执行流程_第2张图片
SpringMVC 执行流程_第3张图片

参考:
Java EE互联网轻量级框架整合开发
带你一步一步手撕Spring MVC源码加手绘流程图
SpringMVC 官方文档

你可能感兴趣的:(Spring)