但行好事
莫论前程❤

WebApplicationContext详解及ContextLoaderListener源码解读

参考:
spring 上下文和spring mvc上下文和web应用上下文servletContext之间的关系

WebApplicationContext详解及ContextLoaderListener源码解读

ServletContext与ApplicationContext详解

Spring源码解读–beanFactory与ApplicationContext

Web容器启动时的加载顺序

简介

由于Web应用比一般应用拥有更多的特性,因此WebApplicationContext扩展了ApplicationContext.

WebApplicationContext是专门为Web应用准备的,它允许从相对于Web根目录的路径中装载配置文件完成初始化工作。

从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象作为属性放置到ServletContext中,以便Web应用环境可以访问Spring应用上下文

img

WebApplicationContext定义了一个常量ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,在上下文启动时,WebApplicationContext实例即以此为key放置在ServletContext的属性列表里 .

img

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";
}
赞(1) 打赏
未经允许不得转载:刘鹏博客 » WebApplicationContext详解及ContextLoaderListener源码解读
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏