AbstractApplicationContext的refresh方法
AbstractApplicationContext的refresh方法
文章目录
- AbstractApplicationContext的refresh方法
- prepareRefresh
- obtainFreshBeanFactory()
- prepareBeanFactory()
- postProcessBeanFactory(beanFactory)
- invokeBeanFactoryPostProcessors(beanFactory)
- registerBeanPostProcessors(beanFactory);
- initMessageSource()
- initApplicationEventMulticaster()
- onRefresh()
- registerListeners()
- finishBeanFactoryInitialization(beanFactory)
- finishRefresh()
AbstractApplicationContext的refresh是Spring IOC容器启动的整个过程,这里记录下refresh方法做的一些事情。
代码如下:
@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {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();}}}
prepareRefresh
刷新前准备工作
- 创建environment并加载System.properties()及System.getenv()到environment中,
obtainFreshBeanFactory()
创建BeanFactory
- 创建一个DefaultListableBeanFactory
- 初始化所有的BeanDefine,XmlBeanDefinitionReader来读取所有Bean的定义,存储在DefaultListableBeanFactory的beanDefinitionMap里面
prepareBeanFactory()
为Bean工厂做准备
- 这里比较重要的就是整个了两个特殊的BeanPostProcessor
1) ApplicationContextAwareProcessor
这个Processor用于执行Aware接口,如果我们写的Bean实现了如下Aware接口,将会执行该Aware接口的对应方法:
EnvironmentAware
EmbeddedValueResolverAware
ResourceLoaderAware
ApplicationEventPublisherAware
MessageSourceAware
ApplicationContextAware
2) ApplicationListenerDetector
这个Processor是用于收集我们自己写的监听器,只要我们的Bean实现了ApplicationListener监听器,那么就会在初始化Bean期间调用postProcessMergedBeanDefinition方法时被收集到这个Bean中,在调用postProcessAfterInitialization注册为Spring的监听器。
postProcessBeanFactory(beanFactory)
扩展点,子类可以重写该方法,完成一些需要在BeanFactory创建后执行的操作。
invokeBeanFactoryPostProcessors(beanFactory)
执行上一步的扩展
registerBeanPostProcessors(beanFactory);
注册上所有的BeanPostProcessors,所有BeanPostProcessor类型的Bean会在此时完成实例化(通过getBean()方法)
initMessageSource()
国际化的,没看过
initApplicationEventMulticaster()
初始化事件广播器,当事件发布器发布事件时,会调用这个广播器来广播事件。
广播器默认实现是SimpleApplicationEventMulticaster,这个监听器支持设置一个线程池来做异步处理。
我们还可以设置errorHandler来统一处理所有监听事件的异常。前提是我们要自己定义一个BeanId为applicationEventMulticaster的ApplicationEventMulticaster。
onRefresh()
扩展点,子类可以重写该方法,完成一些定制的功能
registerListeners()
注册监听器,我们写的监听器也会在这里加上,但是加的是名字,对象并不会在此处实例化,实例化是在上面说的ApplicationListenerDetector.postProcessAfterInitialization(…)方法中来在添加到ApplicationEventMulticaster中的,这里具体加个名字目前自己理解的话,是解决事件监听器scope不为单例时的应用。
finishBeanFactoryInitialization(beanFactory)
在实例化Bean的过程中,会按照顺序执行.,如下:
- resolveBeforeInstantiation会找到类型为InstantiationAwareBeanPostProcessor,且在Bean初始化前对Bean执行操作,可以在此处也返回代理(AOP就这么玩的),beanFactory的hasInstantiationAwareBeanPostProcessors这个属性决定值执不执行。
- 实例化 ----》 AbstractAutowireCapableBeanFactory.doCreateBean()
- populateBean注入属性
- initalizeBean方法调用扩展,顺序如下:
1)如果Bean是BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,会执行者几个的方法Aware的对应方法
2)先执行所有BeanPostProcessor.postProcessBeforeInitialization()
3) 反射调用init方法,如果Bean是InitializingBean,会先执行InitializingBean的afterPropertiesSet方法, 然后在执行自动以的init方法
4)调用所有BeanPostProcessor.applyBeanPostProcessorsAfterInitialization()方法
@PostConstruct标记的方法,是在BeanPostProcessor.postProcessBeforeInitialization() 调用时执行,也就是有一个BeanPostProcessor用于处理标记了该注解的方法(InitDestroyAnnotationBeanPostProcessor),定时器等注解,原理也是一样的,在解析BeanDefinition时,会将这些注解都解析成BeanDefinition的一个属性
finishRefresh()
- 在所有Bean加载完毕后,在容器中找beanId为lifecycleProcessor的LifecycleProcessor,找到则用找到的,没有找到值创建一个默认的DefaultLifecycleProcessor,然后就会执行这个LifecycleProcessor的onRefresh方法。在DefaultLifecycleProcessor执行onRefresh方法时,会去容器中找SmartLifecycle类型的Bean,并执行SmartLifecycle.start()方法,可以在此处扩展整个BeanFactory创建及初始化完成后的操作。
- 发布一个ContextRefreshedEvent事件,SpringMVC就是基于这个事件扩展的
AbstractApplicationContext的refresh方法相关推荐
- 【四】Spring源码分析之启动主流程---AbstractApplicationContext的refresh方法
入口: 在SpringBoot启动的时候,SpringApplication的run方法中 refreshContext(context); 里面最终调用的是AbstractApplicationCo ...
- spring4.1.8初始化源码学习三部曲之三:AbstractApplicationContext.refresh方法
本章是<spring4.1.8初始化源码学习三部曲>系列的终篇,重点是学习AbstractApplicationContext类的refresh()方法: 原文地址:https://blo ...
- 延时加载refresh()方法
先从IOC 容器的初始化过程开始,我们知道IOC 容器读入已经定位的Bean 定义资源是从refresh()方法开始的,我们首先从AbstractApplicationContext 类的refres ...
- 2、AbstractApplicationContext的refresh功能概述
refresh方法是整个Spring容器的核心,其体现了Spring容器的工作流程 refresh方法中调用了13个子方法完成整个工作流程 @Overridepublic void refresh() ...
- SpringBoot bean解析之refresh方法(一)
bean解析是springboot IOC思想的核心, bean解析的核心则是 AbstractApplicationContext 类中的refresh方法: AbstractApplication ...
- spring 中 ApplicationContext 的 refresh 方法做了什么
refresh 方法可以说是Spring中核心的一个方法了,通过这个方法可以获取bean的定义.创建添加bean到spring容器中一个其它扩展功能.记录下相关内容. 有个问题:refresh方法为什 ...
- refresh() 方法简析
IOC 控制反转_牦牛先生的博客-CSDN博客_ioc控制反转和依赖注入Spring Framework 概述https://blog.csdn.net/centrl/article/details/ ...
- [转]bootstrapTable refresh 方法使用简单举例
原文地址:https://blog.csdn.net/lanyang123456/article/details/55805478 本文就bootstrapTable refresh 方法如何传递参数 ...
- Spring的refresh()方法调用过程
Spring的refresh()方法调用过程 refresh()是Spring中比较核心的方法,Spring所有的初始化都在这个方法中完成 具体代码如下 public void refresh() t ...
- bootstrapTable refresh 方法使用简单举例
本文就bootstrapTable refresh 方法如何传递参数做简单举例说明. 下面代码中,一个table,一个button,单击button会触发刷新表格操作. <!DOCTYPE ht ...
最新文章
- 量子计算机人类意识云,意识上传-人类距离永生还要多久(大脑的工作原理很有可能与量子计算机一致)...
- 微信小程序实时获取用户经纬度
- Visual Studio 2015编译Lua 5.3.4遇到的坑
- 学习笔记Hadoop(四)—— Hadoop集群的安装与部署(1)—— 虚拟机安装、java安装
- 74 计算机图形学开源处理库
- Python数据可视化1.2 数据转换
- mybatis insert 重复数据2条_Mybatis框架lt;增gt;:添加一条数据到数据库中,insert...
- python中input数组_python – 在NumPy数组中搜索序列
- 微软是如何使用C#重写C#编译器并将其开源的
- AC日记——红色的幻想乡 洛谷 P3801
- 我的偶像:Garfield 上映
- java 系列1:数据类型转换
- 迭代总结(随时更新)
- 使用iMazing为iPad添加PDF文档
- 产品生命周期管理(PLM)
- js自执行函数(function(){})()前加个分号是什么意思?
- 融云技术分享:融云安卓端IM产品的网络链路保活技术实践
- linux 路由器 限速,Linux服务器限速WonderShaper使用方法 | 陌小九
- 2022智源大会议程公开 | 视觉模型论坛
- jenkins下载插件失败
热门文章
- 如何搜索网易云中的评论
- 正交矩阵和旋转矩阵之间关系和性质总结
- JS打印之指定元素分页,自动插入分页符
- python excel表格去重_EXCEL数据如何去重? Python:这事我比你熟
- 高德地图Amap绘制路线首尾相连问题
- 2022-2028全球与中国电动气动转换器市场现状及未来发展趋势
- 众包专访:开源众包让我安心——开源中国众包使用记录
- 联想服务器修改mac,修改Thinkpad E420的无线网卡MAC地址?
- wine linux 目录,linux中wine的安装及使用
- 【软考系统架构设计师】2012年下系统架构师案例分析历年真题