一、属性设置
对于ApplicationContext,其实例化前必须要设置的就是配置文件的路径--configLocation。例如:
对于非Web环境下的ClasspathXmlApplicationContext,需要通过构造函数或调用setConfigLocation设置配置文件路径;
对于Web环境下的XmlWebApplicationContext,会使用web.xml中配置的contextConfigLocation作为配置文件路径
//另外Web环境下使用的WebXmlApplicationContext还会保存ServletContext对象以及一些Web环境下的参数。
二、刷新上下文
refresh方法基本算是ApplicationContext最重要的方法之一,基本包含了ApplicationContext的大部分功能。需要注意的是,refresh方法并不是在ApplicationContext接口中定义的,而是在其子接口ConfigurableApplicationContext中定义的。下面是refresh的实现(代码位于AbstractApplicationContext):
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备刷新的上下文
prepareRefresh();
// 初始化BeanFactory,并读取配置文件
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 对BeanFactory进行填充
prepareBeanFactory(beanFactory);
try {
// 模版方法,由子类对初始化好的BeanFactory进行额外的处理
postProcessBeanFactory(beanFactory);
// 调用BeanFactoryPostProcessor后处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 注册Bean处理器
registerBeanPostProcessors(beanFactory);
// 初始化Message源,与国际化处理相关
initMessageSource();
// 初始化应用消息广播器,并作为一个Bean注册到BeanFactory中
initApplicationEventMulticaster();
// 模版方法,交由子类实现,刷新前的特殊处理
onRefresh();
// 在注册的bean列表中查找Listener类型的bean,注册到消息广播器中
registerListeners();
// 提前初始化单例bean(非惰性的)
finishBeanFactoryInitialization(beanFactory);
// 通知生命周期处理器LifecycleProcessor刷新过程,并且发出ContextRefreshEvent事件
finishRefresh();
}
catch (BeansException ex) {
//log..
// 销毁已经创建好的bean
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
刷新的流程为:
- 初始化的准备工作,如系统属性或环境变量的准备和验证
- 创建BeanFactory,并读取xml配置文件
- 对BeanFactory进行功能填充
- 通过模版方法模式,交由子类覆盖方法postProcessBeanFactory,对BeanFactory做额外处理
- 激活BeanFactory后处理器
- 注册拦截Bean创建的Bean处理器
- 初始化Message源
- 初始化消息广播器
- 留给子类初始化其他bean
- 将注册的Listener bean注册到消息广播器中
- 提前初始化单例bean(非惰性)
- 完成刷新,发出ContextRefreshEvent事件,并通知生命周期处理器LifecycleProcessor刷新过程
1、环境准备
主要是做些准备工作,对属性进行初始化和验证工作
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
//log...
// 交由子类覆盖
initPropertySources();
// 验证需要的属性是否都已经被放入环境中
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
2、加载BeanFactory
ApplicationContext通过obtainFreshBeanFactory函数创建BeanFactory,自此方法后也就拥有了BeanFactory的所有功能:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//委托给了refreshBeanFactory方法
refreshBeanFactory();
//因为创建BeanFactory实在子类中实现的,所以需要通过getBeanFactory才能获取到实例
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
下面是refreshBeanFactory的实现(位于AbstractRefreshableApplicationContext):
protected final void refreshBeanFactory() throws BeansException {
//如果已经创建过BeanFactory,则销毁所有已经创建的Bean并且重新创建BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//实例化
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//设置一些属性
customizeBeanFactory(beanFactory);
//加载xml配置文件
loadBeanDefinitions(beanFactory);
//将BeanFactory实例设置到ApplicationContext中
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
初始化流程:
- 如果已经创建过,则销毁、清理掉以前创建的BeanFactory
- 实例化BeanFactory
- 定制BeanFactory
- 加载xml配置文件
a、实例化BeanFactory
实例化的代码比较简单,直接新建了一个DefaultListableBeanFactory,并且传入父ApplicationContext(如果存在的话)中的BeanFactory作为父BeanFactory,下面是实例化代码:
protected DefaultListableBeanFactory createBeanFactory() {
//如果存在父ApplicationContext,会通过它获取父BeanFactory传出构造函数
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
getInternalParentBeanFactory实现:
protected BeanFactory getInternalParentBeanFactory() {
return (getParent() instanceof ConfigurableApplicationContext) ?
((ConfigurableApplicationContext) getParent()).getBeanFactory() : getParent();
}
如果父ApplicationContext类型是ConfigurableApplicationContext,则获取其中的BeanFactory,否则将父ApplicationContext作为BeanFactory传入。
b、定制BeanFactory
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//allowBeanDefinitionOverriding:是否允许覆盖同名称的不同定义的对象
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
//allowCircularReferences:是否允许循环依赖
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
主要是对allowBeanDefinitionOverriding和allowCircularReferences属性进行设置,在AbstractRefreshableApplicationContext中并未对这两个属性进行设置,而是需要由子类来进行配置。
c、加载配置文件
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 为指定的BeanFactory创建XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
//