DispatcherServlet创建流程
1.前言
在前面我们通过继承HttpServlet。覆写doGet和doPost方法,在web.xml配置相关的servlet就可以实现相关的web服务功能。
在Spring中,DispatcherServlet是Spring MVC的核心组件,他会被注册到Servlet Web容器(例如Tomcat)中,接收请求,然后做请求分发,调用Controller方法处理请求,接收响应返回给客户端。
2.DispatcherServlet
在早期版本的Spring
MVC中,我们发现我们自己不用再extends HttpServlet
,覆写doGet
和doPost
方法。因为在Spring中,它已经使用DispatcherServlet
帮我们处理了。使用web.xml文件配置DispatcherServlet:
1 |
|
还记得前面讲Servlet的时候:
1 |
|
这是Servlet规范的要求,所有的Java Web服务都需要这样配置,进行Servlet注册。我们发现只是将自定义的servlet替换成Spring给我们提供的DispatcherServlet。
2.1 DispatcherServlet继承体系
先看看DispatcherServlet相关类的继承关系:
类似如XXXAware
型的接口,表示对XXX可以进行感知,通俗解释就是:如果在某个类中想要使用spring的一些东西,就可以通过实现XXXAware接口来告诉Spring,Spring看到后就能给你传送过来,而接收的方式就是通过实现该接口的唯一方法setXXX()。
EnvironmentCapable:(Capable-有能力的)顾名思义,该接口表示具有Environment的能力,也就是可以提供Environment,该接口唯一的方法就是getEnvironment(),它将返回一个Environment对象
在HttpServletBean中的Environment里面封装了ServletContext、ServletConfig、JndiProperty、系统环境变量和系统属性,这里都封装到了其propertySources属性下。在实际开发中,当web容器初始化后,在web.xml中对DispatcherServlet设置的init-param就会封装到Environment里面:
我们注意到HttpServletBean
继承了HttpServlet
,所以可以得知DispatcherServlet本质也是一个servlet,也遵循servlet相关规范。
3. DispatcherServlet创建流程
1 |
|
3.1 反射实例化Servlet
我们在web.xml文件配置相关的Servlet,当服务器启动的时候:
web服务器会读取web.xml文件。并根据
<servlet>
元素的配置实例化指定的Servlet
类。实例化
DispatcherServlet
:- 服务器调用
Class.forName("org.springframework.web.servlet.DispatcherServlet")
加载DispatcherServlet
类。 - 使用
DispatcherServlet
的无参构造函数创建其实例。
先调用父类 FrameworkServlet 的构造方法,再调用自己的构造方法;
- 服务器调用
1 |
|
3.2 调用 init 方法
Servlet接口定义的是一套处理网络请求的规范,所有实现Servlet的类,都需要实现它那五个方法,其中最主要的是两个生命周期方法
init()
和destroy()
,还有一个处理请求的service()
。
当Servlet第一次被请求时,Servlet容器
就会开始调用init方法
来初始化一个Servlet对象出来,但是这个方法在后续请求中不会在被Servlet容器调用只能调用一次,调用这个方法时,Servlet容器会传入一个ServletConfig对象进来从而对Servlet对象进行初始化,因此创建Servlet实例后,服务器调用
DispatcherServlet
的 init
方法进行初始化。
3.2.1 HttpServletBean-init()
该init() 由HttpServletBean
实现:
1 |
|
3.2.2 FrameworkServlet-initServletBean()
initServletBean方法在HttpServletBean是一个空方法,由FrameworkServlet实现:
1 |
|
这里的核心代码只有2句,一句用于初始化WebApplicationContext,另一句用于初始化FrameworkServlet。
3.2.3 FrameworkServlet-initWebApplicationContext()
1 |
|
initWebApplicationContext共做了三件事:
- 获取spring的根容器rootContext
- 设置WebApplicationContext并根据情况调用onRefresh方法
- 将WebApplicationContext设置到ServletContext中
不管通过哪种方式调用,onRefresh()方法肯定且只会调用一次,而且dispatchServlet正是通过重写这个模板方法来实现初始化的*
3.2.4 DispatchServlet-onRefresh()
onRefresh方法在FrameworkServlet是一个空方法,由DispatchServlet
实现:
1 |
|
3.2.5 DispatchServlet-initStrategies()
(Strategies-战略;策略;规划)方法非常简单,目的就是初始化springmvc的9大组件
1 |
|
initHandlerMappings,initHandlerAdapters,这俩货是不是在哪里见到过,没错。就是SpringMVC请求流程中的一环。所以HandlerMappings,HandlerAdapters实在此处创建的。至此,DispatchServlet的init方法就执行完成了,然后启动整个SpringMVC容器。
博客说明
文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,不用于任何的商业用途。如有侵权,请联系本人删除。谢谢!