在web.xml中,配置ContextLoaderListener

 <!-- 配置Listener,用来创建Spring容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <context-param>
<!-- 配置Listener参数:告诉它Spring的配置文件位置,它好去创建容器 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:application-context*.xml</param-value>
</context-param>

说明:<listener>标签中,ContextLoaderListener用来创建Spring容器;而<context-param>标签,用来指定了spring配置文件的位置,该两个标签共同起作用,也就可以在web项目启动后,成功的创建了Spring容器了。 

分析如下:

1.ContextLoaderListener实现了ServletContextListener接口,ServletContextListener是Java EE标准接口之一,类似tomcat,jetty的java容器启动时便会触发该接口的contextInitialized。也就是说会激活调用ContextLoaderListener的contextInitialized()方法

2.ContextLoaderListener类中的contextInitialized方法如下

	/**
* Initialize the root web application context.
*/
@Override
public void contextInitialized(ServletContextEvent event) {
initWebApplicationContext(event.getServletContext());
}

  

3.我们在进入到ClassLoader类的initWebApplicationContext( )方法内部,会注入ServletContext   servletContext的参数对象,同时帮我们返回一个WebApplicationContext容器对象,代码如下:

  

public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {

	/** 此处省略部分代码 */

	Log logger = LogFactory.getLog(ContextLoader.class);
servletContext.log("Initializing Spring root WebApplicationContext");
if (logger.isInfoEnabled()) {
logger.info("Root WebApplicationContext: initialization started");
}
long startTime = System.currentTimeMillis(); try { if (this.context == null) {
/**
* 重要,该方法会帮我们创建WebApplicationConntext,并赋值给ContextLoaderListener类的context对象。
* 说明:ContextLoaderListener类的context属性来自于它的父类
*/
this.context = createWebApplicationContext(servletContext);
}
if (this.context instanceof ConfigurableWebApplicationContext) {
ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context;
if (!cwac.isActive()) { /** 此处省略部分代码 */ configureAndRefreshWebApplicationContext(cwac, servletContext);
}
}
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); ClassLoader ccl = Thread.currentThread().getContextClassLoader();
if (ccl == ContextLoader.class.getClassLoader()) {
currentContext = this.context;
} /** 此处省略部分代码 */ return this.context;
} }

  debug打断点我们可以看到注入ServletContext   servletContext的参数对象ApplicationContextFacade类型的对象,内部是通过Map来实现的,用来加载Spring的配置文件。

  也就是说该方法执行完后,我们就会拿到WebApplicationContext类型的Spring容器对象。那么该方法内部具体是如何加载Spring配置文件的呢,是如何创建WebApplicationContext对象?我们接着往下看

  4.我们可以看到该行代码:this.context = createWebApplicationContext(servletContext);  该方法用于创建WebApplicationContext对象,并赋值给context属性。WebApplicationContext是一个接口类,本质上返回的是XmlWebApplicationContext,它就是Spring容器了

 

  5.我们再进入到createWebApplicationContext(servletContext)方法中:

	protected WebApplicationContext createWebApplicationContext(ServletContext sc) {
Class<?> contextClass = determineContextClass(sc);
if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {
throw new ApplicationContextException("Custom context class [" + contextClass.getName() +
"] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]");
}
return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
}

  会将刚才注入的ApplicationContextFacade对象传入,用于指定Spring的配置文件位置,它的内部是通过Map来实现的,也就是说,该类会解析<context-param>标签的内容,加载Spring配置文件,有了配置文件就可以初始化容器了

  

  6.createWebApplicationContext( ) 调用determineContextClass( )方法

     determineContextClass有如下代码:

  contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName());

 

 7.很明显是从defaultStrategies中加载的

  ContextLoader 类中有段静态代码:会加载默认配置,也就是会加载<param-value>classpath:application-context*.xml</param-value>中的xml文件

    static {
try {
ClassPathResource resource = new ClassPathResource("ContextLoader.properties", ContextLoader.class);
defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
}
catch (IOException ex) {
throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
}
}

  

  8.ContextLoader.properties 文件内容如下:

  org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext

  此时,determineContextClass( )方法返回的是XmlWebApplicationContext对象,之后回到3步骤中的configureAndRefreshWebApplicationContext( )方法

  9.  configureAndRefreshWebApplicationContext的细节调用

    configureAndRefreshWebApplicationContext 调用了AbstractApplicationContext的refresh方法

    refresh 方法调用了obtainFreshBeanFactory

    obtainFreshBeanFactory 调用了AbstractRefreshableApplicationContext类的refreshBeanFactory方法

    refreshBeanFactory调用了XmlWebApplicationContext的loadBeanDefinitions

    loadBeanDefinitions中加载了对应的applicationContext.xml

ContextLoaderListener加载过程的更多相关文章

  1. 深入理解 spring 容器,源码分析加载过程

    Spring框架提供了构建Web应用程序的全功能MVC模块,叫Spring MVC,通过Spring Core+Spring MVC即可搭建一套稳定的Java Web项目.本文通过Spring MVC ...

  2. web.xml加载过程

    web.xml加载过程:1 启动WEB项目的时候,容器(如:Tomcat)会读他的配置文件web.xml读两个节点  <listener></listener>和<con ...

  3. springmvc源码分析——入门看springmvc的加载过程

    本文将分析springmvc是如何在容器启动的时候将各个模块加载完成容器的创建的. 我知道在web.xml文件中我们是这样配置springmvc的: 可以看到,springmvc的核心控制器就是Dis ...

  4. web.xml的加载过程配置详解

      一:web.xml加载过程 简单说一下,web.xml的加载过程.当我们启动一个WEB项目容器时,容器包括(JBoss,Tomcat等).首先会去读取web.xml配置文件里的配置,当这一步骤没有 ...

  5. java web.xml被文件加载过程及加载顺序小结

    web.xml加载过程(步骤): 1.启动WEB项目的时候,容器(如:Tomcat)会去读它的配置文件web.xml.读两个节点: <listener></listener> ...

  6. Java web 加载过程

    1.Web容器初始化过程 2.SpringMVC中web.xml配置 3.认识ServletContextListener 4.认识ContextLoaderListener 5.Dispatcher ...

  7. Java Web应用的加载过程

    在介绍Spring IoC和MVC的加载前,用这篇小文章简单地记录下,最简单的web应用的加载过程. 一.从最简单的web应用出发 使用Eclipse直接创建一个Dynamic Web Project ...

  8. web.xml被文件加载过程,各节点加载顺序总结

    web.xml被文件加载过程,各节点加载顺序总结 博客分类: J2EE WebXMLSpringServletBean  今天2010-3-11日,上班无事,想来将web.xml项目描述文件的加载过程 ...

  9. 工厂模式模拟Spring的bean加载过程

    一.前言    在日常的开发过程,经常使用或碰到的设计模式有代理.工厂.单例.反射模式等等.下面就对工厂模式模拟spring的bean加载过程进行解析,如果对工厂模式不熟悉的,具体可以先去学习一下工厂 ...

随机推荐

  1. See you~(二维树状数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1892 See you~ Time Limit: 5000/3000 MS (Java/Others)  ...

  2. cesium编程入门(四)界面介绍及小控件隐藏

    感性认识 界面介绍,viewer Geocoder : 查找位置工具,查找到之后会将镜头对准找到的地址,默认使用bing地图 Home Button :视角返回初始位置. Scene Mode Pic ...

  3. YUI3组件框架之plugin

    plugin相关源码分析: plugin功能包括如下几个模块, 简单分析如下: pluginhost-base 维护对象 this._plugins = {}: 并提供方法: plug.unplug. ...

  4. 从零开始学习前端开发 — 15、CSS3过渡、动画

    一.css3过渡 语法: transition: 过渡属性 过渡时间 延迟时间 过渡方式; 1.过渡属性(transition-property) 取值:all 所有发生变化的css属性都添加过渡 e ...

  5. OKMX6Q在ltib生成的rootfs基础上制作带QT库的根文件系统

    ltib每次执行后会在其目录下生成rootfs目录,并以其为基础生成rootfs.ext2.gz文件,而litb自带的QT库又太老,所以想到按照飞凌的<OKMX6X-S2-Qt4.8.5移植手册 ...

  6. 对[UIApplication sharedApplication]理解

    [ sharedApplication]返回UIApplication * application = nil; +(UIApplication*) shareApplication{ if(appl ...

  7. Asp.net Core 跨域配置

    一般情况WebApi都是跨域请求,没有设置跨域一般会报以下错误 No 'Access-Control-Allow-Origin' header is present on the requested ...

  8. Xcode 单元测试

    项目创建后自动创建的单元测试文件夹, 文件夹名为项目名+tests, xcode6后貌似没有选择是否添加测试target的选择了. 默认生成的如下图 提供的断言如下 typedefNS_ENUM(NS ...

  9. programing

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  10. webpack 基本打包方法

    webpack的打包基本配置文件webpack.config.js 可以在webpack.config.js里面写好配置:比如前章节所总结的四大核心 |-- add.js // 定义一个普通加法函数 ...