赞
踩
DispatcherServlet源码分析
SpringMVC核心的就是DispatcherServlet,所有的请求都会转发到DispatcherServlet,让后在通过DispatcherServlet执行具体的控制层(Handler) 返回modelAndView给客户端视图展示。
DispatcherServlet与Servlet关系
关系:DispatcherServlet继承FrameworkServlet继承HttpServlet
流程执行关系:
HttpServlet service方法 判断请求方法的类型
FrameworkServlet doService
DispatcherServlet doService
DispatcherServlet源码流程分析
现在先从最开始的web.xml文件进行分析,我们首先配置了contextConfigLocation如下所示:
继承关系如下图所示:
上图中的ServletContextListener该类位于servlet-api.jar包中(再tomcat的自带lib中可以找到)
ContextLoaderListener实现了ServletContextListener接口,该接口保证了在能够为客户端提供服务之前向ServletContext中添加任何对象。每个Web应用都有一个ServletContext与之相关联,启动时被创建,关闭时被销毁,并且ServletContext在全局范围内有效。ServletContextListener的核心逻辑就是初始化WebApplicationContext实例并放入ServletContext中。
我们之所以使用了ContextLoaderListener是为了避免下面这种硬编码配置:
ApplicationContext ac = new ClassPathXmlApplecation("applicationContext.xml")
再来说说ContextLoaderListener的实际步骤是:
讲完了ContextLoaderListener再来讲讲web.xml中另一个重要配置DispatcherServlet,对于DispatcherServlet的配置如下所示:
接下来我们先给出DispatcherServlet的类层次结构,如下图所示:
Spring容器启动时, 在org.springframework.web.servlet.handler.AbstractHandlerMethodMapping类
遍历IOC容器中所有bean
判断是否有@Controller和@RequestMapping注解
调用链关系如下图:
容器启动时, 在HttpServletBean类里面的init方法里面进行初始化
最终执行DispatcherServlet的initStrategies方法进行组件的初始化
初始化上传文件解析器(或者是多部分请求解析器)
初始化本地化解析器
初始化主题解析器
初始化处理器映射器
初始化处理器适配器
初始化处理器异常解析器
初始化请求到视图名翻译器
初始化视图解析器
初始化重定向数据管理器
虽然HTTP1.1报文头一共有八种,常用的:GET、POST、PUT、DELETE,不太常用的:HEAD、TRACE、CONNECT、OPTIONS,但是实际上FrameworkServlet并没有实现CONNECT和HEAD。他们分别对应着doXXX()方法。
对于不同的方法,Spring统一的将他们引入到processRequest方法中,该方法完成了以下操作:
仍然是准备工作,将webApplicationContext,localeResolver等属性注入request中,然后继续由doDispatch方法进行处理,
doDispatch方法的处理逻辑为:
第一步:将MultipartContent类的request转化为MultipartHttpServletRequest类型的request
第二步:首先获取到HandlerExecutionChain,HandlerExecutionChain结构很简单,包括一个我们具体处理请求的Controller层方法的对象handler,以及拦截器interceptors、interceptorList。如果没有获取到相应的HandlerExecutionChain,则会返回404。
第三步:若如果没有找到对应的Handler则通过response向用户报错
第四步:根据当前的Handler寻找对应的HandlerAdapter(遍历寻找)
第五步:缓存处理,根据Last-Modified缓存机制(第一次成功请求后如果在第二次请求之间内容没有改变,那么返回304状态码),Controller需要实现LastModified接口
第六步:顺序调用拦截器的preHandle()方法,如果不符合拦截器的拦截规则则会同时调用afterCompletion()方法
第七步:逻辑处理,通过适配器中转调用Handler(处理用户定义的逻辑)并返回视图
第八步:调用拦截器的postHandle()
第九步:调用processDispatchResult()对请求结果进行处理。如果业务处理过程中有异常抛出,调用processHandlerException()对异常进行处理,这里会调用我们自定义的HandlerExceptionResolvers进行处理,然后返回一个异常处理结果的ModelAndView对象。
第十步:执行拦截器afterCompletion方法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。