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

刷新前准备工作

  1. 创建environment并加载System.properties()及System.getenv()到environment中,

obtainFreshBeanFactory()

创建BeanFactory

  1. 创建一个DefaultListableBeanFactory
  2. 初始化所有的BeanDefine,XmlBeanDefinitionReader来读取所有Bean的定义,存储在DefaultListableBeanFactory的beanDefinitionMap里面

prepareBeanFactory()

为Bean工厂做准备

  1. 这里比较重要的就是整个了两个特殊的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的过程中,会按照顺序执行.,如下:

  1. resolveBeforeInstantiation会找到类型为InstantiationAwareBeanPostProcessor,且在Bean初始化前对Bean执行操作,可以在此处也返回代理(AOP就这么玩的),beanFactory的hasInstantiationAwareBeanPostProcessors这个属性决定值执不执行。
  2. 实例化 ----》 AbstractAutowireCapableBeanFactory.doCreateBean()
  3. populateBean注入属性
  4. 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()

  1. 在所有Bean加载完毕后,在容器中找beanId为lifecycleProcessor的LifecycleProcessor,找到则用找到的,没有找到值创建一个默认的DefaultLifecycleProcessor,然后就会执行这个LifecycleProcessor的onRefresh方法。在DefaultLifecycleProcessor执行onRefresh方法时,会去容器中找SmartLifecycle类型的Bean,并执行SmartLifecycle.start()方法,可以在此处扩展整个BeanFactory创建及初始化完成后的操作。
  2. 发布一个ContextRefreshedEvent事件,SpringMVC就是基于这个事件扩展的

AbstractApplicationContext的refresh方法相关推荐

  1. 【四】Spring源码分析之启动主流程---AbstractApplicationContext的refresh方法

    入口: 在SpringBoot启动的时候,SpringApplication的run方法中 refreshContext(context); 里面最终调用的是AbstractApplicationCo ...

  2. spring4.1.8初始化源码学习三部曲之三:AbstractApplicationContext.refresh方法

    本章是<spring4.1.8初始化源码学习三部曲>系列的终篇,重点是学习AbstractApplicationContext类的refresh()方法: 原文地址:https://blo ...

  3. 延时加载refresh()方法

    先从IOC 容器的初始化过程开始,我们知道IOC 容器读入已经定位的Bean 定义资源是从refresh()方法开始的,我们首先从AbstractApplicationContext 类的refres ...

  4. 2、AbstractApplicationContext的refresh功能概述

    refresh方法是整个Spring容器的核心,其体现了Spring容器的工作流程 refresh方法中调用了13个子方法完成整个工作流程 @Overridepublic void refresh() ...

  5. SpringBoot bean解析之refresh方法(一)

    bean解析是springboot IOC思想的核心, bean解析的核心则是 AbstractApplicationContext 类中的refresh方法: AbstractApplication ...

  6. spring 中 ApplicationContext 的 refresh 方法做了什么

    refresh 方法可以说是Spring中核心的一个方法了,通过这个方法可以获取bean的定义.创建添加bean到spring容器中一个其它扩展功能.记录下相关内容. 有个问题:refresh方法为什 ...

  7. refresh() 方法简析

    IOC 控制反转_牦牛先生的博客-CSDN博客_ioc控制反转和依赖注入Spring Framework 概述https://blog.csdn.net/centrl/article/details/ ...

  8. [转]bootstrapTable refresh 方法使用简单举例

    原文地址:https://blog.csdn.net/lanyang123456/article/details/55805478 本文就bootstrapTable refresh 方法如何传递参数 ...

  9. Spring的refresh()方法调用过程

    Spring的refresh()方法调用过程 refresh()是Spring中比较核心的方法,Spring所有的初始化都在这个方法中完成 具体代码如下 public void refresh() t ...

  10. bootstrapTable refresh 方法使用简单举例

    本文就bootstrapTable refresh 方法如何传递参数做简单举例说明. 下面代码中,一个table,一个button,单击button会触发刷新表格操作. <!DOCTYPE ht ...

最新文章

  1. 量子计算机人类意识云,意识上传-人类距离永生还要多久(大脑的工作原理很有可能与量子计算机一致)...
  2. 微信小程序实时获取用户经纬度
  3. Visual Studio 2015编译Lua 5.3.4遇到的坑
  4. 学习笔记Hadoop(四)—— Hadoop集群的安装与部署(1)—— 虚拟机安装、java安装
  5. 74 计算机图形学开源处理库
  6. Python数据可视化1.2 数据转换
  7. mybatis insert 重复数据2条_Mybatis框架lt;增gt;:添加一条数据到数据库中,insert...
  8. python中input数组_python – 在NumPy数组中搜索序列
  9. 微软是如何使用C#重写C#编译器并将其开源的
  10. AC日记——红色的幻想乡 洛谷 P3801
  11. 我的偶像:Garfield 上映
  12. java 系列1:数据类型转换
  13. 迭代总结(随时更新)
  14. 使用iMazing为iPad添加PDF文档
  15. 产品生命周期管理(PLM)
  16. js自执行函数(function(){})()前加个分号是什么意思?
  17. 融云技术分享:融云安卓端IM产品的网络链路保活技术实践
  18. linux 路由器 限速,Linux服务器限速WonderShaper使用方法 | 陌小九
  19. 2022智源大会议程公开 | 视觉模型论坛
  20. jenkins下载插件失败

热门文章

  1. 如何搜索网易云中的评论
  2. 正交矩阵和旋转矩阵之间关系和性质总结
  3. JS打印之指定元素分页,自动插入分页符
  4. python excel表格去重_EXCEL数据如何去重? Python:这事我比你熟
  5. 高德地图Amap绘制路线首尾相连问题
  6. 2022-2028全球与中国电动气动转换器市场现状及未来发展趋势
  7. 众包专访:开源众包让我安心——开源中国众包使用记录
  8. 联想服务器修改mac,修改Thinkpad E420的无线网卡MAC地址?
  9. wine linux 目录,linux中wine的安装及使用
  10. 【软考系统架构设计师】2012年下系统架构师案例分析历年真题