Spring源码解读(1) 启动流程的那点事儿

在一般的web应用程序,我们倘若用到Spring的话,需要在web.xml中配置以下的信息来使一些容器,例如TomcatJetty等来加载Spring。

以下是web.xml的部分代码配置

<!-- 指定spring配置文件路径 -->
<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>classpath:config/spring-*.xml</param-value>
</context-param>

<!-- 监听器:解析spring配置文件,在服务器启动的时候会创建该监听器实例.实现了ServletContextListener,在ServletContext对象
   创建或者销毁的时候,监听器中的方法会被执行 -->
<listener>
   <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


而Spring主要通过ContextLoaderListener类在应用启动时加载其服务,通过源码可知,ContextLoaderListener实现了

ServletContextListener类,重写了contextInitialized方法




现在让我们着重看一下这个initWebApplicationContext这个方法到底做了什么事呢。

这个方法的实现在org.springframework.web.context.ContextLoader

我们只截取部分重要代码


来看一下这段代码做了什么事呢。 首先,判断一下Web程序的上下文对象是否存在,如果不存在则通过createWebApplicationContext创建一个上下文对象(XmlWebApplicationContext),其实现原理就是通过反射机制,有兴趣的同学可以自行点进去看源码,这里不多做介绍。但是,我们是如何知道他创建的是一个XmlWebApplicationContext对象呢?接下来是解惑时间。

细心的同学会发现,上面我们已经说过了,这个方法的实现在org.springframework.web.context.ContextLoader下,让我们回到ContextLoader类看看,到底有什么玄机。

	static {
		// Load default strategy implementations from properties file.
		// This is currently strictly internal and not meant to be customized
		// by application developers.
		try {
			ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, ContextLoader.class);
			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
		}
		catch (IOException ex) {
			throw new IllegalStateException("Could not load 'ContextLoader.properties': " + ex.getMessage());
		}
	}

没错,非常有意思是ContextLoader类里面有一个静态代码块,在类启动加载的时候就已经去读取org\springframework\web\context\ContextLoader.properties这个配置文件并进行加载了。


现在让我们继续去看configureAndRefreshWebApplicationContext这个类


首先,设置一个contextId。设置web.xml文件配置(从contextConfigLocation 这个param获取(String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM)),如果未配置,则默认读取/WEB-INF/applicationContext.xml),然后我们着重wac.refresh()这个方法。

ConfigurableApplicationContext(wac)接口定义了模版方法,AbstractApplicationContext类实现了wac类,并重写了wac类中的refresh方法,在该方法里,会完成加载资源、配置文件(包括配置文件中的自定义标签)解析、Bean定义注册、组件初始化。


在看refresh方法之前,我们先看一下customizeContext(sc, wac)这个方法。refresh方法放到下一章讲解。


这段代码主要是调用ContextLoader对象的determineContextInitializerClasses方法来获取实现了ApplicationContextInitializer接口的类对象列表,并使用每个ApplicationContextInitializer对象来对spring容器做更多的初始化操作。

配置和示例如下:

在web.xml中加入一下配置
	<context-param>
		<param-name>globalInitializerClasses</param-name>
		<param-value>
			com.deepbaytech.service.impl.Initializer1
		</param-value>
	</context-param>

创建一个类来实现ApplicationContextInitializer接口,对spring容器做更多的初始化操作。

public class Initializer1 implements ApplicationContextInitializer {
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.err.println("Initializer1初始化完成");
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值