DispatcherServlet是springmvc最重要的组成部分,听名字就知道它负责一个请求到响应的流转,本篇主要讲DispatcherServlet的启动过程。
思考一个把问题?为什么DispatcherServlet初始化后,Spring的Ioc容器就会启动,容器中的Bean是什么时候注册到容器中的?
实际上整个SpringMvc的启动过程分为俩个阶段:
- ContextLoaderListener初始化,实例化IOC容器,并将此容器注册到ServletContext中。
DispatcherServlet初始化,建立自己的上下文,也注册到ServletContext中。
见下面这段web.xml的配置(springboot不在我们这篇文章讨论之列。)
1 | <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" |
ContextLoaderListener初始化
见web.xml这一段
1 | <context-param> |
关键逻辑:
ContextLoaderListener采用了很典型的适配器模式,继承了ContextLoader,实现了ServletContextListener接口。
在contextInitialized()->initWebApplicationContext()
1 |
|
configureAndRefreshWebApplicationContext方法
1 | protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { |
DispatcherServlet初始化
相关的xml配置
1 | <!-- Servlet that dispatches request to registered handlers (Controller implementations). --> |
类的继承关系:DispatcherServlet–>FrameworkServlet–>HttpServletBean–>HttpServlet
HttpServletBean重写了Serlvet的init方法,封装了spring的web容器启动的过程。
HttpServletBean
init()方法
1 | /** |
FrameworkServlet
FrameworkServlet的Override了HttpServletBean的initServletBean方法,在该方法通过initWebApplicationContext初始化了webApplicationContext
1 | /** |
FrameworkServlet.initWebApplicationContext()
1 | protected WebApplicationContext initWebApplicationContext() { |
重点方法,FrameworkServlet.configureAndRefreshWebApplicationContext(),初始化ConfigurableWebApplicationContext并且执行refresh。
1 |
|
DispatcheServlet
重点方法onRefresh:逻辑见下图,重点方法initStrategies。组件的优先级:自己注入的Bean>DespatchServlet.properties中的Bean
1 |
|
总结
这里的context默认是XmlWebApplicationContext,见contextLoader
1 | //文件内容:org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext |
见DispatcherServlet
1 | public static final Class<?> DEFAULT_CONTEXT_CLASS = XmlWebApplicationContext.class; |
启动时候如何加载的init-param,见HttpServletBean的代码,推荐下去试试BeanWrapper
1 | //BeanWrapper实际是BeanWrapperImpl【DispatcherServlet】 |