上一个方法setConfigLocations(configLocations)链接
下面我们根据代码debug看一下代码执行流程
@Test
public void test(){
ApplicationContext context =new ClassPathXmlApplicationContext("jdbcTemplate.xml");
}
/**
* 创建一个新的ClassPathXmlApplicationContext,从给定的XML文件路径加载信息并且自动刷新上下文
* Create a new ClassPathXmlApplicationContext, loading the definitions
* from the given XML file and automatically refreshing the context.
* @param configLocation resource location
* @throws BeansException if context creation failed
*/
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
/**
* Create a new ClassPathXmlApplicationContext with the given parent,
* loading the definitions from the given XML files.
* @param configLocations array of resource locations
* @param refresh whether to automatically refresh the context,
* loading all bean definitions and creating all singletons.
* Alternatively, call refresh manually after further configuring the context.
* @param parent the parent context
* @throws BeansException if context creation failed
* @see #refresh()
*/
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
refresh()是spring中非常重要的方法,定义了上述bean的一系列创建过程
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 1.准备刷新上下文,主要是设置启动日期和活跃标志,检查系统和环境属性等初始化操作
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 2.调用子类获取一个BeanFactory,作为applicationContext的成员变量,子类可以创建一个新的BeanFactory也可以返回它持 有的一个BeanFactory的单例实例但是后一种情况如果上下文刷新多次的话会抛出一种非法状态异常
// 设置是否允许修改bean信息和是否允许bean循环引用的boolean型参数
// 通过授权一个或多个BeanDefinitionReader读取bean信息到这个BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 3.为BeanFactory设置一些上下文的属性,比如告诉BeanFactory使用上下文的类加载器和后处理器等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 4.在上下文内置的BeanFactory标准初始化完成后,此时所有的Bean已经被加载但是还没有被实例化,允许在上下文 的内部实现中注册特别的BeanPostProcessor来进行修改Bean信息
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 5.在普通bean对象实例化之前,实例化并执行所有已经注册到上下文中的BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 6.在普通bean对象实例化之前,实例化并执行所有已经注册到上下文中的BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 7.初始化消息源,主要设置一些国际化问题
initMessageSource();
// Initialize event multicaster for this context.
// 8.初始化事件广播组
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 8.空方法,留给子类拓展,初始化其它特殊的bean
onRefresh();
// Check for listener beans and register them.
// 9.将监听器添加的事件广播组中
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 10.完成BeanFactory的初始化并实例化所有非懒加载的bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 11.完成刷新操作并发布对应的事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// 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();
}
}
}
接下来逐个详细的解析每个方法
- prepareRefresh();
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
- prepareBeanFactory(beanFactory);
- postProcessBeanFactory(beanFactory);
- invokeBeanFactoryPostProcessors(beanFactory);
- registerBeanPostProcessors(beanFactory);
- initMessageSource();
- initApplicationEventMulticaster();
- onRefresh();
- registerListeners();
- finishBeanFactoryInitialization(beanFactory);
- finishRefresh();