【Spring】从源码分析Spring配置文件的加载

使用Spring必须在web.xml中写如下配置:

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>

通过ContextLoaderListener加载Spring的配置文件applicationContext.xml,实例化所有单例的bean,加载完毕后将Spring的配置存储到application内置对象中,名称为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。下面通过源码大致分析下整个过程。

看看org.springframework.web.context.ContextLoaderListener这个监听器类的源码:(源码只列出其中部分)

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {
	private ContextLoader contextLoader;

	/**
	 * Initialize the root web application context.
	 */
	public void contextInitialized(ServletContextEvent event) {
		this.contextLoader = createContextLoader();
		if (this.contextLoader == null) {
			this.contextLoader = this;
		}
		this.contextLoader.initWebApplicationContext(event.getServletContext());
	}

	// 省略其他部分

}

initWebApplicationContext(event.getServletContext())方法用于加载Spring的配置文件,传入的是application内置对象,加载成功后放入application对象中

进入initWebApplicationContext(event.getServletContext())方法:

在ContextLoader类中:

public WebApplicationContext initWebApplicationContext(ServletContext servletContext){
	// 加载Spring的配置文件
	this.context = createWebApplicationContext(servletContext, parent);
	// 向servletContext中设置属性名为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE的值,保存的就是Spring的配置文件内容,以后需要使用Spring的配置文件时就可以通过此名字获取
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);
}
</span>

再进入createWebApplicationContext(servletContext,parent)方法,

protected WebApplicationContext createWebApplicationContext(ServletContext sc, ApplicationContext parent){
	Class<?> contextClass = determineContextClass(sc);
	ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);
        // 获取在web.xml中配置文件中指定的Spring配置文件路径
	wac.setConfigLocation(sc.getInitParameter(CONFIG_LOCATION_PARAM));
	return wac;
}

这里的CONFIG_LOCATION_PARAM就是初始值是:

public static final String CONFIG_LOCATION_PARAM = “contextConfigLocation”;

这个contextConfigLocation就是在web.xml中配置的,所以就能根据配置找到Spring的配置文件applicationContext.xml。

注:这里的源码用的Spring版本可能比较低,较新版本的源码可能有些不同,但基本思想都差不多。

上面说的加载完毕后将Spring的配置存储到application内置对象中,名称为WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。在程序中也是通过这个名称来Spring配置文件中的信息的,例如通过一个监听器说明:

public class TestServletContextListener implements ServletContextListener{

	private ApplicationContext context = null;

	@Override
	public void contextDestroyed(ServletContextEvent arg0) {
		// TODO Auto-generated method stub
	}

	@Override
	public void contextInitialized(ServletContextEvent se) {
		// 获得Spring的配置文件
		context = WebApplicationContextUtils.getWebApplicationContext(se.getServletContext());
		se.getServletContext().setAttribute("aa", ...);
	}
}

看看WebApplicationContextUtils类的getWebApplicationContext(ServletContext sc)方法的源码:

public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
	return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
}

可以看到就是通过调用getWebApplicationContext(sc,WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);方法来获取Spring配置文件的信息的。

Author:顾故

Sign:别输给曾经的自己

时间: 2024-10-20 01:45:24

【Spring】从源码分析Spring配置文件的加载的相关文章

【Spring源码分析】非懒加载的Bean实例化过程(下篇)

doCreateBean方法 上文[Spring源码分析]非懒加载的Bean实例化过程(上篇),分析了单例的Bean初始化流程,并跟踪代码进入了主流程,看到了Bean是如何被实例化出来的.先贴一下AbstractAutowireCapableBeanFactory的doCreateBean方法代码: 1 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[]

看看Spring的源码(一)——Bean加载过程

首先Web项目使用Spring是通过在web.xml里面配置org.springframework.web.context.ContextLoaderListener初始化IOC容器的. <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> 那就以此为切入点顺藤摸瓜. public class

vscode源码分析【八】加载第一个画面

第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 第四篇:vscode源码分析[四]程序启动的逻辑,最初创建的服务 第五篇:vscode源码分析[五]事件分发机制 第六篇:vscode源码分析[六]服务实例化和单例的实现 第七篇:vscode源码分析[七]主进程启动消息通信服务 先复习一下! 在第一节中,我们提到: app.ts(src\vs\co

【Nutch2.2.1源码分析之一】Nutch加载配置文件的方法

1.NutchConfiguration.java用于加载及获取Nutch的相关参数. Utility to create Hadoop Configurations that include Nutch-specific  resources. 即它会加载hadoop及nutch中的参数文件. 关键是2个create()方法,它加载了参数文件的同时,又返回了Configuration对象. 2.不带参数的create方法 public static Configuration create()

Dubbo源码分析系列---扩展点加载

扩展点配置: 约定: 在扩展类的jar包内,放置扩展点配置文件:META-INF/dubbo/接口全限定名,内容为:配置名=扩展实现类全限定名,多个实现类用换行符分隔.(摘自dubbo文档) 示例: 假如我现在想使用自己定义的协议Myprotocol,在resources目录下新建META-INF/dubbo/com.alibaba.dubbo.rpc.Protocol目录文件,文件内容定义: myprotocol=com.selrain.MyProtocol 实现类内容: public cla

Spring AMQP 源码分析 08 - XML 配置

### 准备 ## 目标 通过 XML 配置文件使用 Spring AMQP ## 前置知识 <Spring AMQP 源码分析 07 - MessageListenerAdapter> ## 相关资源 Sample code:<https://github.com/gordonklg/study>,rabbitmq module 源码版本:Spring AMQP 1.7.3.RELEASE ## 测试代码 gordon.study.rabbitmq.springamqp.XmlC

Spring AMQP 源码分析 05 - 异常处理

### 准备 ## 目标 了解 Spring AMQP Message Listener 如何处理异常 ## 前置知识 <Spring AMQP 源码分析 04 - MessageListener> ## 相关资源 Offical doc:<http://docs.spring.io/spring-amqp/docs/1.7.3.RELEASE/reference/html/_reference.html#exception-handling> Sample code:<ht

Spring AMQP 源码分析 07 - MessageListenerAdapter

### 准备 ## 目标 了解 Spring AMQP 如何用 POJO 处理消息 ## 前置知识 <Spring AMQP 源码分析 04 - MessageListener> ## 相关资源 Offical doc:<http://docs.spring.io/spring-amqp/docs/1.7.3.RELEASE/reference/html/_reference.html#message-listener-adapter> Sample code:<https:

Spring AMQP 源码分析 06 - 手动消息确认

### 准备 ## 目标 了解 Spring AMQP 如何手动确认消息已成功消费 ## 前置知识 <Spring AMQP 源码分析 04 - MessageListener> ## 相关资源 Offical doc:<http://docs.spring.io/spring-amqp/docs/1.7.3.RELEASE/reference/html/_reference.html#message-listener-adapter> Sample code:<https:

spring事务源码分析结合mybatis源码(一)

最近想提升,苦逼程序猿,想了想还是拿最熟悉,之前也一直想看但没看的spring源码来看吧,正好最近在弄事务这部分的东西,就看了下,同时写下随笔记录下,以备后查. spring tx源码分析 这里只分析简单事务也就是DataSourceTransactionManager 首先肯定找入口了,看过spring源码的同学一定都会找spring tx的入口就是在TxAdviceBeanDefinitionParser这里将解析tx的配置,生成TransactionInterceptor对象,这个也就是一