到底什么才是Spring容器呢?我们需要分清楚以上两个类的区别。
● ApplicationContext是BeanFactory的子接口
● BeanFactory是一个底层的IOC容器,提供了IOC容器的基本实现,而ApplicationContext则是BeanFactory的超集提供了丰富的企业级特性。
● ApplicationContext是委托DefaultListableBeanFactory来实现Bean的依赖查找和依赖注入。
接下来就详细介绍一下Spring容器的完整生命周期都做了哪些事情。
首先,入口是AbstractApplicationContext.refresh()方法其实是启动容器。这是一个抽象类,许多的应用上下文都实现了这个类。比如最常见的:
org.springframework.context.support.ClassPathXmlApplicationContext
接下来看下源代码中是长什么样子。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// 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);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
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();
}
}
}
其中的阶段做的事情非常之多,阅读时难免会陷入某一个阶段中去,而无法做到对全局做一个把握,这里就是分解一下各个阶段所做的事情,从而对有一个全局的视角。Spring的体系比较庞杂,我们只能各个击破。
AbstractApplicationContext#prepareRefresh();
该方法为容器启动做准备
a. 启动时间
b. 容器状态标识
c. 初始化PropertySources-->initPropertySources()空方法留给子类实现
d. 检验Environment中的必须属性
e. 初始化事件监听集合
f. 初始化早期Spring事件集合
AbstractApplicationContext#obtainFreshBeanFactory();
通过模板方法模式在子类中实现容器的获取结果是DefaultListableBeanFactory。
Tips: 大多数应用上下文的实现都继承了AbstractRefreshableApplicationContext。
a. 刷新Spring应用上下文底层
BeanFactoryAbstractRefreshableApplicationContext#refreshBeanFactory()
i. 销毁或关闭BeanFactory,如果已经存在的话。
ii. 创建BeanFactory:createBeanFactory()
iii. 设置BeanFactory Id
iv. 设置“是否允许BeanDefinition重复定义”
v. 设置“是否允许循环依赖”
vi. 加载BeanDefinition:loadBeanDefinitions(DefaultListableBeanFactory)
vii. 关联新建BeanFactory到Spring应用上下文
b. 返回Spring应用上下文底层BeanFactory=>getBeanFactory()
AbstractApplicationContext#prepareBeanFactory()
a. 关联classloader
b. 设置Bean表达式处理器(SpringEL相关的内容)
c. 添加PropertyEditorRegistrar实现:ResourceEditorRegistrar
d. 添加Aware回调接口BeanPostProcessor实现:ApplicationContextAwareProcessor
e. 添加Aware回调接口作为依赖注入接口
f. 注册ResolvableDependency内建的非Bean对象:BeanFactory、ResourceLoader、ApplicationEventPublisher以及ApplicationContext
g. 注册ApplicationListenerDetector对象
i. 对于符合ApplicationListener接口且是单例的Bean记录到singletonsName。后面会作为ApplicationListener关联到ApplicationContext中。
h. 注册LoadTimeWeaverAwareProcessor对象(AOP相关)
i. 注册单例对象:Environment、Java System Properties以及OS环境变量
针对容器的扩展
a. postProcessBeanFactory(beanFactory)
i. 是个空方法,需要子类去扩展这个方法
b. InvokeBeanFactoryPostProcessors(beanFactory)
i. 迭代所有BeanFactoryPostProcessor判断它是否是BeanDefinitionRegistryPostProcessor类型
1. 如果是则执行其postProcessBeanDefinitionRegistry方法,并在registryProcessors集合中加入当前迭代对象BeanFactoryPostProcessor。
2. 否则直接加入regularPostProcessors集合中,表示是常规的PostProcessor。
ii. Spring容器中的BeanFactoryPostProcessor有可能实现了PriorityOrdered、Ordered接口,也可能没有实现。对他们进行分别归类之后按照PriorityOrdered、Ordered、常规的BeanFactoryPostProcessor的集合顺序去执行。
iii. 分别遍历处理registryProcessors和regularpostProcessors两个集合对象,执行迭代对象的postProcessBeanFactory方法,因为其实集合的对象都实现了BeanFactoryPostProcessor接口。
AbstractApplicationContext#registerBeanPostProcessors(beanFactory);// 针对Bean的扩展
i. 注册PriorityOrdered类型的BeanPostProcessor Beans
ii. 注册Ordered类型的BeanPostProcessor Beans
iii. 注册普通的BeanPostProcessor Beans
iv. 注册MergedBeanDefinitionPostProcessor Beans
v. 注册ApplicationListenerDetector对象
initMessageSource()
● 在Spring容器中依赖查找MessageSource并根据情况设置其层次性
● 如果IOC容器中没有则创建一个DelegatingMessageSource并设置其层次性,然后在Spring容器中注册MessageSource单例对象
AbstractApplicationContext#initApplicationEventMulticaster()
a. 在Spring容器中判断并依赖查找ApplicationEventMulticaster对象,并赋值给当前容器的applicationEventMulticaster
b. 如果IOC容器中没有则创建一个SimpleApplicationEventMulticaster,然后在Spring容器中注册ApplicationEventMulticaster单例对象。
初始化特殊Bean->onRefresh()
这个方法是一个空实现,提供给子类扩展。比如StaticWebApplicationContext、AbstractRefreshableWebApplicationContext子类则是提供了关于theme主题的实现。
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
AbstractApplicationContext#registerListeners()
a. 添加当前应用上下文所关联的ApplicationListener集合对象
b. 添加BeanFactory所注册ApplicationListener Beans
c. 广播早期Spring事件
AbstractApplicationContext#finishBeanFactoryInitialization(beanFactory)
a. BeanFactory关联ConversionService Bean(如果存在的话)
b. 添加StringValueResolver对象提供处理占位符操作
c. 依赖查找LoadTimeWeaverAware Bean
d. BeanFactory临时ClassLoader置为null
e. BeanFactory冻结配置
f. BeanFactory初始化非延迟单例Beans:beanFactory#preInstantiateSingletons()
AbstractApplicationContext#finishRefresh()
a. 清除ResourceLoader缓存:clearResourceCaches()
b. 初始化LifecycleProcessor对象:initLifecycleProcessor()
c. 调用LifecycleProcessor#onReFresh())方法
d. 发布Spring应用上下文已刷新事件:ContextRefreshedEvent
e. 向MBeanServer托管LiveBeans(可以通过jconsole查看)
AbstractApplicationContext#start()
a. 这个方法一般起辅助作用,可以不调用它。。
b. 作用一:启动LifecycleProcessor
c. 作用二:发布Spring应用上下文已启动事件:ContextStartedEvent事件
AbstractApplicationContext#stop()
a. 跟start方法一样是辅助作用。
b. 作用一:停止LifecycleProcessor
c. 作用二:发布Spring应用上下文已停止事件:ContextStoppedEvent事件
AbstractApplicationContext#close()
a. Spring容器设置状态标识:active=false,closed=true
b. Live Beans JMX撤销托管
c. 发布Spring应用上下文的已关闭事件
d. 关闭LifecycleProcessor
e. 销毁Spring Beans
f. 关闭BeanFactory
g. 回调onClose()
h. 如果ShutdownHook这个线程不为null,remove ShutDown Hook Thread
其中start和stop方法用的很少,它们只是起到一个辅助IOC容器的作用,对了解IOC容器的整个生命周期不是非常重要,重点关注refresh方法即可。