参考:
spring 上下文和spring mvc上下文和web应用上下文servletContext之间的关系
WebApplicationContext详解及ContextLoaderListener源码解读
ServletContext与ApplicationContext详解
Spring源码解读–beanFactory与ApplicationContext
简介
由于Web应用比一般应用拥有更多的特性,因此WebApplicationContext扩展了ApplicationContext.
WebApplicationContext是专门为Web应用准备的,它允许从相对于Web根目录的路径中装载配置文件完成初始化工作。
从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象作为属性放置到ServletContext中,以便Web应用环境可以访问Spring应用上下文
WebApplicationContext定义了一个常量ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
,在上下文启动时,WebApplicationContext实例即以此为key放置在ServletContext的属性列表里 .
WebApplicationContext初始化
WebApplicationContext
需要ServletContext
实例,必须先启动Web容器,然后才能启动WebApplicationContext
,可以在web.xml
文件中配置自启动的Servlet或定义Web容器监听器,就可以完成启动Spring Web应用上下文的工作(Web容器启动,马上初始化Spring实现的Servlet(即ContextLoaderListener
),这个Servlet的任务就是完成WebApplicationContext
的初始化,在初始化WebApplicationContext
过程中,会通过Servlet获取ServletContext
实例的引用,并保存到WebApplicationContext
中,初始化WebApplicationContext
完成后,把WebApplicationContext
实例当做属性保存到ServletContext
的属性列表中,代码如下,至此,Servlet初始化完毕。为何要这样初始化?因为Web容器是不变的,Spring去适应Web容器,而不是Web容器去适应Spring,相当于Web容器是甲方,它把处理HTTP请求的任务外包出来,Structs、Spring MVC等等Web请求处理框架都可以去当接单当乙方,接单之后就要按照甲方的需求去完成,Web容器提供了一些基础的接口暴露给乙方,乙方在这些接口的规范下去开发自己的东西,所以如果先初始化WebApplicationContext
,那么Spring和Web容器要建立连接的话,就要后启动的Web容器自己去和Spring建立连接,这是不可能的,Web容器没有这些能力去做,它永远不会改变自己,只会让别人来适应自己,所以只能先启动Web容器,再去通过Web容器提供了自启动Servlet的能力,Spring去实现这样一个Servlet,在Web容器初始化之后,Web容器去初始化Spring的Servlet,利用这个时机,Spring在这个Servlet内部完成自己的初始化工作,并自己主动去找ServletContext
建立连接,而Web容器只需要完成自己的天职,实例化Servlet即可,不用做额外的工作,额外的工作都由Spring来做,因为Spring是乙方,乙方适应甲方).
web.xml中的<context-param>
配置是在web容器初始化的时候当做初始化参数,web容器初始化完成后,这个参数以键值对形式被保存到ServletContext中,可以用getInitParameter(key)
方法从ServletContext
的对象中取出web上下文初始化参数值,key为参数名,返回的是参数值。
上述web容器上下文和spring上下文的启动过程对应的源码:
- web.xml配置
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
- ContextLoaderListener源码
public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}
}
- ContextLoader源码
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
...
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
...
}
web.xml中<context-param>
配置对应的源码
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:applicationContext-web.xml,
classpath:applicationContext-shiro.xml,
classpath:applicationContext-jedis.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
ContextLoaderListener
继承自 ContextLoader
ContextLoader
对应的源码中包含属性
public class ContextLoader {
public static final String CONFIG_LOCATION_PARAM = "contextConfigLocation";
}
评论前必须登录!
注册