一:前言 web.xml文件一般位于WEB-INF目录下。 如果读过tomcat源码,就知道在tomcat在启动过程的初始化阶段,会读取web.xml的配置。 二:示例spring父容器配置
springMvc子容器配置
以上内容均为web.xml中配置,分为spring父容器和springMVC子容器的配置。 子容器的ApplicationContext会和父容器的ApplicationContext相关联。 三:解读3.1 ContextLoaderListenerContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法,使用ServletContextListener接口,开发者能够在为客户端请求提供服务之前向ServletContext中添加任意的对象。这个对象在ServletContext启动的时候被初始化,然后在ServletContext整个运行期间都是可见的。 每一个Web应用都要一个ServletContext与之相关联。ServletContext对象在应用启动时被创建,在应用关闭的时候被销毁。ServletContext在全局范围内有效,类似于应用中的一个全局变量。 在ServletContextListener中的核心逻辑便是初始化WebApplicationContext实例并存放至ServletContext中。 ServletContextListener 接口如下,tomcat等容器启动过程中会调用contextInitialized方法,加载ApplicationContext容器 public interface ServletContextListener extends EventListener { public void contextInitialized(ServletContextEvent sce); public void contextDestroyed(ServletContextEvent sce); } 3.2 DispatcherServlet(一)介绍 DispatcherServlet的继承关系如下图:
在Spring中,ContextLoaderListener只是辅助功能,用于创建WebApplicationContext类型实例,而真正的逻辑实现其实是在DispatcherServlet中进行的,DispatcherServlet是实现servlet接口的实现类。 servlet是一个java编写的程序,此程序是基于HTTP协议的,在服务器端运行的(如Tomcat),是按照servlet规范编写的一个Java类。主要是处理客户端的请求并将其结果发送到客户端。servlet的生命周期是由servlet的容器来控制的,它可以分为3个阶段:初始化,运行和销毁。 (1)初始化阶段 - servlet容器加载servlet类,把servlet类的.class文件中的数据读到内存中。
- servlet容器创建一个ServletConfig对象。ServletConfig对象包含了servlet的初始化配置信息。
- servlet容器创建一个servlet对象。
- servlet容器调用servlet对象的init方法进行初始化。
(2)运行阶段。 当servlet容器接收到一个请求时,servlet容器会针对这个请求创建servletRequest和servletResponse对象,然后调用service方法。并把这两个参数传递给service方法。service方法通过servletRequest对象获得请求的信息。并处理该请求。再通过servletResponse对象生成这个请求的响应结果。然后销毁servletRequest和servletResponse对象。我们不管这个请求是post提交的还是get提交的,最终这个请求都会由service方法来处理。 (3)销毁阶段。 当Web应用被终止时,servlet容器会先调用servlet对象的destory方法,然后再销毁servlet对象,同时也会销毁与servlet对象相关联的servletConfig对象。我们可以在destory方法的实现张红,释放servlet所占用的资源,如关闭数据库连接,关闭文件输入输出流等。 servlet的框架是由两个Java包组成:javax.servlet和javax.servlet.http。在javax.servlet包中定义了所有的servlet类都必须实现或扩展的通用接口和类,在javax.servlet.http包中定义了采用HTTP通信协议的HttpServlet类。 servlet被设计成请求驱动,servlet的请求可能包含多个数据项,当Web容器接收到某个servlet请求时,servlet把请求封装成一个HttpServletRequest对象,然后把对象传给servlet的对应的服务方法。 (二)DispatcherServlet的初始化 在servlet初始化阶段会调用其init方法,所以我们首先要查看在DispatcherServlet中是否重写了init方法。我们在其父类HttpServletBean中找到了该方法 init() 在初始化过程中会逐级调用相关方法: init() -》 initServletBean() -》 initWebApplicationContext() -》 createWebApplicationContext(rootContext) -》 createWebApplicationContext(ApplicationContext parent) -》 configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) 其中,configureAndRefreshWebApplicationContext方法中添加了一个ApplicationListener,它在onRefresh(ApplicationContext context) 的initStrategies(ApplicationContext context)方法中,对相关组件进行了初始化: protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); } |