Spring IOC容器生命周期阶段总结
发布日期:2021-06-30 13:43:58 浏览次数:2 分类:技术文章

本文共 6795 字,大约阅读时间需要 22 分钟。

Spring IOC容器生命周期

BeanFactory和ApplicationContext有何区别?

到底什么才是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的体系比较庞杂,我们只能各个击破。

1. Spring应用上下文启动准备阶段

AbstractApplicationContext#prepareRefresh();

该方法为容器启动做准备

a. 启动时间b. 容器状态标识c. 初始化PropertySources-->initPropertySources()空方法留给子类实现d. 检验Environment中的必须属性e. 初始化事件监听集合f. 初始化早期Spring事件集合

2. BeanFactory创建阶段

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()

3. BeanFactory初始化阶段

AbstractApplicationContext#prepareBeanFactory()
a. 关联classloaderb. 设置Bean表达式处理器(SpringEL相关的内容)c. 添加PropertyEditorRegistrar实现:ResourceEditorRegistrard. 添加Aware回调接口BeanPostProcessor实现:ApplicationContextAwareProcessore. 添加Aware回调接口作为依赖注入接口f. 注册ResolvableDependency内建的非Bean对象:BeanFactory、ResourceLoader、ApplicationEventPublisher以及ApplicationContextg. 注册ApplicationListenerDetector对象	i. 对于符合ApplicationListener接口且是单例的Bean记录到singletonsName。后面会作为ApplicationListener关联到ApplicationContext中。h. 注册LoadTimeWeaverAwareProcessor对象(AOP相关)i. 注册单例对象:Environment、Java System Properties以及OS环境变量

4. BeanFactory后置处理阶段

针对容器的扩展

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接口。

5. BeanFactory注册BeanPostProcessor阶段

AbstractApplicationContext#registerBeanPostProcessors(beanFactory);// 针对Bean的扩展
i. 注册PriorityOrdered类型的BeanPostProcessor Beans	ii. 注册Ordered类型的BeanPostProcessor Beans	iii. 注册普通的BeanPostProcessor Beans	iv. 注册MergedBeanDefinitionPostProcessor Beans	v. 注册ApplicationListenerDetector对象

6. 初始化国际化

initMessageSource()

● 在Spring容器中依赖查找MessageSource并根据情况设置其层次性

● 如果IOC容器中没有则创建一个DelegatingMessageSource并设置其层次性,然后在Spring容器中注册MessageSource单例对象

7. 初始化应用事件广播器

AbstractApplicationContext#initApplicationEventMulticaster()
a. 在Spring容器中判断并依赖查找ApplicationEventMulticaster对象,并赋值给当前容器的applicationEventMulticasterb. 如果IOC容器中没有则创建一个SimpleApplicationEventMulticaster,然后在Spring容器中注册ApplicationEventMulticaster单例对象。

8. Spring应用上下文刷新阶段

初始化特殊Bean->onRefresh()

这个方法是一个空实现,提供给子类扩展。比如StaticWebApplicationContext、AbstractRefreshableWebApplicationContext子类则是提供了关于theme主题的实现。

this.themeSource = UiApplicationContextUtils.initThemeSource(this);

9. Spring注册监听器阶段

AbstractApplicationContext#registerListeners()
a. 添加当前应用上下文所关联的ApplicationListener集合对象b. 添加BeanFactory所注册ApplicationListener Beansc. 广播早期Spring事件

10. BeanFactory初始化完成阶段

AbstractApplicationContext#finishBeanFactoryInitialization(beanFactory)
a. BeanFactory关联ConversionService Bean(如果存在的话)b. 添加StringValueResolver对象提供处理占位符操作c. 依赖查找LoadTimeWeaverAware Beand. BeanFactory临时ClassLoader置为nulle. BeanFactory冻结配置f. BeanFactory初始化非延迟单例Beans:beanFactory#preInstantiateSingletons()

11. Spring应用上下文启动完成阶段

AbstractApplicationContext#finishRefresh()
a. 清除ResourceLoader缓存:clearResourceCaches()b. 初始化LifecycleProcessor对象:initLifecycleProcessor()c. 调用LifecycleProcessor#onReFresh())方法d. 发布Spring应用上下文已刷新事件:ContextRefreshedEvente. 向MBeanServer托管LiveBeans(可以通过jconsole查看)

12. Spring应用上下文启动阶段

AbstractApplicationContext#start()
a. 这个方法一般起辅助作用,可以不调用它。。b. 作用一:启动LifecycleProcessorc. 作用二:发布Spring应用上下文已启动事件:ContextStartedEvent事件

13. Spring应用上下文停止阶段:

AbstractApplicationContext#stop()
a. 跟start方法一样是辅助作用。b. 作用一:停止LifecycleProcessorc. 作用二:发布Spring应用上下文已停止事件:ContextStoppedEvent事件

14. Spring应用上下文关闭阶段:

AbstractApplicationContext#close()
a. Spring容器设置状态标识:active=false,closed=trueb. Live Beans JMX撤销托管c. 发布Spring应用上下文的已关闭事件d. 关闭LifecycleProcessore. 销毁Spring Beansf. 关闭BeanFactoryg. 回调onClose()h. 如果ShutdownHook这个线程不为null,remove ShutDown Hook Thread

其中start和stop方法用的很少,它们只是起到一个辅助IOC容器的作用,对了解IOC容器的整个生命周期不是非常重要,重点关注refresh方法即可。

在这里插入图片描述

转载地址:https://jeffsheng.blog.csdn.net/article/details/112800752 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:源码剖析:AQS-AbstractQueuedSynchronizer
下一篇:相信自己的判断。

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2024年04月23日 15时17分40秒