文章目录

  • Pre
  • refresh()
  • Spring的设计
  • 源码验证


Pre

接上文 Spring5源码 - 03 普通对象对应的BeanDefinition是如何存入DefaultListableBeanFactory#beanDefinitionMap 源码分析


refresh()

这里我们只粗略的看一下其中的逻辑,真的很复杂

@Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing.  1:准备刷新上下文环境 prepareRefresh();// Tell the subclass to refresh the internal bean factory. 2:获取告诉子类初始化Bean工厂ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context. 3:对bean工厂进行填充属性prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses. 第四:留给子类去实现该接口postProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context. 调用bean工厂的后置处理器.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.  调用bean的后置处理器registerBeanPostProcessors(beanFactory);beanPostProcess.end();// Initialize message source for this context.  初始化国际化资源处理器.    initMessageSource();// Initialize event multicaster for this context. 创建事件多播器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.  这个方法同样也是留给子类实现的    springboot也是从这个方法进行启动tomat的.onRefresh();// Check for listener beans and register them.  把我们的事件监听器注册到多播器上registerListeners();// Instantiate all remaining (non-lazy-init) singletons.  实例化我们剩余的单实例bean.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.  最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的)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();contextRefresh.end();}}}

Spring的设计

我们接着来看 spring 是在哪一个方法调用中完成扫描的 即什么时候初始化BeanDefinition, 并且把这个BeanDefinition放到bdMap集合中。

通过debug分析可以得出

invokeBeanFactoryPostProcessors(beanFactory);

主要工作

执行所有的需要被执行的BeanFactoryPostProcessor
1.1 执行Spring内置的BeanFactoryPostProcessor (完成Bean的扫描) 【其实就是ConfigurationClassPostProcessor】
1.2 执行开发人员提供的BeanFactoryPostProcessor


源码验证

再细说一下主要的设计思想

看方法名 invokeBeanFactoryPostProcessors 也能猜到 主要是执行 BeanFactoryPostProcessors

既然是 BeanFactoryPostProcessors , 那就说明有很多 BeanFactoryPostProcessor

BeanFactoryPostProcessor是个接口,spring实现了一部分,当然开发人员也可以实现BeanFactoryPostProcessor接口。

那Spring该如何决定这些接口实现类的先后顺序呢? 这就是Spring IOC 核心的地方。

先说说Spring的几个比较核心的子类和实现类

主要干的两个活

  1. 执行直接实现了BeanFactoryPostProcessor
  2. 执行实现了BeanDefinitionRegistryPostProcessor

举个例子 ,假设我们有个自己的类 ,实现了 子类BeanDefinitionRegistryPostProcessor接口

ArtisanTest02 implements BeanDefinitionRegistryPostProcessor

那么你不仅要把BeanDefinitionRegistryPostProcessor的接口实现,还要实现其父类BeanFactoryPostProcessor接口的方法,那么在调用invokeBeanFactoryPostProcessors的时候 ,这两个方法都会被执行 。

假设还有一个类 ,ArtisanTest03 实现了 BeanFactoryPostProcessor 接口

 ArtisanTest03  implements BeanFactoryPostProcessor

来运行看下效果


Spring5源码 - 04 invokeBeanFactoryPostProcessors 源码解读_1相关推荐

  1. Spring5源码 - 05 invokeBeanFactoryPostProcessors 源码解读_3细说invokeBeanDefinitionRegistryPostProcessors

    文章目录 Pre 细说invokeBeanDefinitionRegistryPostProcessors 流程图 源码分析 解析配置类 parser.parse(candidates) 配置类注册到 ...

  2. Spring5源码 - 05 invokeBeanFactoryPostProcessors 源码解读_2

    文章目录 Pre 源码解读 总体流程 源码分析 细节解析 [初始化对应的集合 & 遍历用户自己手动添加的后置处理器] [调用实现了PriorityOrdered接口的BeanDefinitio ...

  3. ubuntu安装python_ubuntu18.04下源码编译安装最新版本Python3

    原文链接:ubuntu18.04下源码编译安装最新版本Python3 截止到2019年4月9日,Python3最新的版本是3.7.3. 在ubuntu18.04中已经安装的Python3版本是3.6. ...

  4. 【ElasticSearch】Es 源码之 CcrRestoreSourceService 源码解读

    文章目录 1.概述 2.构造方法 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的CcrRestoreSourceSe ...

  5. 【ElasticSearch】Es 源码之 AutoFollowCoordinator 源码解读

    文章目录 1.概述 2.构造方法 3. start方法 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的AutoFol ...

  6. 【ElasticSearch】Es 源码之 CleanerService 源码解读

    文章目录 1.概述 2.构造方法 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的CleanerService ,其中 ...

  7. 【ElasticSearch】Es 源码之 Exporters 源码解读

    文章目录 1.概述 2.start 2.1 initExporters 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件 ...

  8. 【ElasticSearch】Es 源码之 CacheService 源码解读

    文章目录 1.概述 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的LifecycleComponent ,其中初始化 ...

  9. 【ElasticSearch】Es 源码之 AsyncSearchMaintenanceService 源码解读

    文章目录 1.概述 1.概述 在博客 [ElasticSearch]Es 源码之 LifecycleComponent 源码解读 中初始化了相关插件的LifecycleComponent ,其中初始化 ...

最新文章

  1. Linux 问题解决 :/lib/systemd/systemd-journald 占用内存过高
  2. 通过案例学调优之--AWR baseline对比生成AWR报告
  3. 数组的reduce方法
  4. parted--大于2T的分区工具
  5. c++17(2)-枚举类enum class
  6. 深入了解EntityFramework——Lazy Loading与Eager Loading
  7. Resharper进阶一:简要介绍
  8. 写作新手想少走弯路,尽快赚到钱,必须要知道的
  9. GoWeb开发_Iris框架讲解(二):Get、Post、Put等请求及数据返回格式
  10. <树莓派>——无法向U盘写入文件
  11. 基于A*启发式搜索解决迷宫问题
  12. deecamp训练营
  13. macOS 访达的隐藏小技巧
  14. 【小程序】小程序里跳转网页链接
  15. iPhone 屏幕尺寸
  16. 【美团 技术篇】美团推荐算法实践
  17. php wordpress 代码模板,wordpress模板代码详解
  18. 客制化键盘编程_客制化键盘QMK固件入门-修改keyboard和keymap
  19. 校园失物招领系统,失物招领系统,校园失物招领管理系统毕设作品
  20. oracle 与赛门铁克,Oracle与赛门铁克认证Veritas数据中心解决方案

热门文章

  1. android edittext 联想,Android 输入法联想问题
  2. C++ >>和<<读写文本文件
  3. sql 精读(六)获取每个类别中最受欢迎的商品
  4. 链表c的经典实现(一)
  5. 计算机专业的金书,《计算机专业英语》书评,金书网
  6. vb表格控件_(超级干货)ExcelVBA拆分表格并分别发送邮件增强版
  7. vue 改变domclass_基于 vue 开发甘特图组件的心路历程(兼设计分享)
  8. 文巾解题 53. 最大子序和
  9. python怎么打开ipynb文件_如何优雅的打开.ipynb文件
  10. tensorflow2中如何设置GPU的使用