Spring MVC 执行流程


dispatcherServlet 类关系

类名作用
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的组件和流程图
实例组件和运行流程

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值