本文通过FileSystemXmlApplicationContext来分析spring的初始化过程,下面是
FileSystemXmlApplicationContext继承关系图
测试程序的Bean和配置文件如下
public class TestBean {
public TestBean(List<String> testList){
System.out.println(testList.size());
}
public void print(){
System.out.println("bean run...");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="TestBean" class="test.TestBean" name="BeanName">
<constructor-arg >
<list>
<value>zhanglun</value>
<value>zhanglun111</value>
</list>
</constructor-arg>
</bean>
</beans>
入口主函数如下,通过main函数作为入口,对spring源码进行调试分析
public class MaiClass {
public static void main(String[] args){
FileSystemXmlApplicationContext fileSystemXmlApplicationContext =
new FileSystemXmlApplicationContext("classpath:spring-config.xml");
TestBean testBean = (TestBean) fileSystemXmlApplicationContext.getBean("TestBean");
testBean.print();
}
}
进入FileSystemXmlApplicationContext的构造方法,FileSystemXmlApplicationContext通过refresh方法对上下文对象就行初始化,完成BeanDefinitions的定位、载入和注册
public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
具体refresh方法的实现,参照FileSystemXmlApplicationContext的父类AbstractApplicationContext
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
//这里是在子类中启动refreshBeanFactory的地方
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);//设置beanFacory的后置处理
//调用BeanFatory的后置处理器,这些后置处理器是在Bean定义中向容器注册的
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//注册bean的后置处理器,在Bean创建过程中调用
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//对上下文中的消息源进行初始化
// Initialize message source for this context.
initMessageSource();
//初始化上下文中的事件机制
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
//初始化其他特殊的Bean
// Initialize other special beans in specific context subclasses.
onRefresh();
//检查监听Bean并将这些Bean像容器中注册
// Check for listener beans and register them.
registerListeners();
//初始化所有的(non-lazy-init)单件
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//发布容器事件,结束Refresh过程
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
//防止Bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件Bean
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
//重置active标志
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
我们主要关注obtainFreshBeanFactory方法,此方法完成BeanDefinitions在BeanFactory中的定位、载入、注册,并返回ConfigurableListableBeanFactory对象,下面查看AbstractApplictionContext的obtainFreshBeanFactory方法实现
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();//beanFactory是个成员变量
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
查看AbstractRefreshableApplicationContext中refreshBeanFactory方法
protected final void refreshBeanFactory() throws BeansExcepti