本节主要讲Spring MVC的DispatcherServlet初始化, Servlet是不能自己启动,是由web容器(比如tomcat)启动和调用Servlet初始化的。DispatcherServlet实现和扩展了javax.Servlet,它是Spring MVC的核心。首先贴一下基础配置文件,web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- 定义需要初始化的applicationcontext配置 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:applicationContext-hello.xml </param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Processes application requests --> <servlet> <servlet-name>hello</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/hello-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
web.xml 中配置的 ContextLoaderListener 会初始化 XmlWebApplicationContext, 这个类的作用类似于之前分析Spring中的 ClassPathXmlApplicationContext 类,XmlWebApplicationContext 是 Spring MVC中的 WebApplicationContext, 它会读取 web.xml 配置的 contextConfigLocation, 负责完成所有其他spring工程的context初始化(至少包括载入其他工程的xml和初始化bean)。
下面继续分析DispatcherServlet的初始化过程。先看一下类结构,HttpServlet是由 servlet-api.jar 包提供的 java通用的servlet实现,FrameworkServlet是spring的继承实现
// DispatcherServlet 初始化会调用父类FrameworkServlet的 init() 方法 public void init(){ // 具体初始化 initServletBean(); } // FramworkServlet类实现 protected final void initServletBean() { this.webApplicationContext = initWebApplicationContext(); initFrameworkServlet(); } // 此方法保证创建WebApplicationContext,并对它进行刷新更新配置文件,即全面的初始化 protected WebApplicationContext initWebApplicationContext() { // 若存在WebApplicationContext // 则对context进行配置,函数内部会调用 onRefresh 载入配置和初始化 configureAndRefreshWebApplicationContext(cwac); .... // 若不存在,则创建WebApplicationContext, // 对context进行刷新,载入配置和初始化 onRefresh(wac); } // onRefresh 方法最终在子类即 DispatcherServlet 中实现,完成 初始化刷新配置流程 // DispatcherServlet 类 protected void onRefresh(ApplicationContext context) { initStrategies(context); } // 进行一系列的bean初始化,每一步都会初始化相应的bean,负责运行时处理各自的任务 protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); // 注册 HandlerMapping 处理类 initHandlerAdapters(context); // 注册 HandlerAdapter 处理类 initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); // 注册视图解析器 initFlashMapManager(context); }