接着上文《spring源码阅读(2)-- 容器启动之加载BeanDefinition》,当spring加载完所有BeanDefinition时,并不会马上去创建bean,而是先配置beanFactory,例如设置一下装配规则和判断是否需要创建一些指定的bean。

1   protected voidprepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {2         //Tell the internal bean factory to use the context's class loader etc.
3 beanFactory.setBeanClassLoader(getClassLoader());4         beanFactory.setBeanExpressionResolver(newStandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));5         beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));6
7         //Configure the bean factory with context callbacks.8         //添加ApplicationContextAwareProcessor用于处理实现了EnvironmentAware、EmbeddedValueResolverAware、ApplicationContextAware接口的bean
9         beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));10         //忽略以下bean的依赖注入
11         beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);12         beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);13         beanFactory.ignoreDependencyInterface(MessageSourceAware.class);14         beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);15         beanFactory.ignoreDependencyInterface(EnvironmentAware.class);16
17         //BeanFactory interface not registered as resolvable type in a plain factory.18         //MessageSource registered (and found for autowiring) as a bean.19         //注册自动装配模式下的特殊依赖,例如被注入的是BeanFactory类型,那么注入的就是beanFactory
20         beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);21         beanFactory.registerResolvableDependency(ResourceLoader.class, this);22         beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);23         beanFactory.registerResolvableDependency(ApplicationContext.class, this);24
25         //Detect a LoadTimeWeaver and prepare for weaving, if found.
26         if(beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {27             beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory));28             //Set a temporary ClassLoader for type matching.
29             beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));30 }31
32         //Register default environment beans.
33         if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {34 beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());35 }36         if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {37 beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());38 }39         if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {40 beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());41 }42     }

  当设置完beanFactory,接下来就是执行BeanFactoryPostProcessor。BeanFactoryPostProcessor是spring容器启动时暴露给用户的一个扩展点,允许用户在spring创建bean之前做修改或动态添加bean,动态注册bean可以使用BeanFactoryPostProcessor的子类BeanDefinitionRegistryPostProcessor。BeanFactoryPostProcessor接口定义如下:

1  public interfaceBeanFactoryPostProcessor {2
3     void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throwsBeansException;4
5 }

  当我们实现了BeanFactoryPostProcessor,spring是怎么去执行的呢?

  spring容器在执行刷新时,当加载完BeanDefinition和配置好beanFactory时,会进入AbstractApplicationContext.invokeBeanFactoryPostProcessors,方法里首先调用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors去执行实现了BeanFactoryPostProcessor的postProcessBeanFactory方法,然后再判断是否新添加了loadTimeWeaver这个bean,如果有,添加LoadTimeWeaverAwareProcessor

1     protected voidinvokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {2 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());3
4         //Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime5         //(e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
6         if (beanFactory.getTempClassLoader() == null &&beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {7             beanFactory.addBeanPostProcessor(newLoadTimeWeaverAwareProcessor(beanFactory));8             beanFactory.setTempClassLoader(newContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));9 }10     }

  进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法,方法里首先判断beanFactory是不是一个bean注册中心,如果是,循环遍历传入的BeanFactoryPostProcessor,判断是否是BeanDefinitionRegistryPostProcessor的实现,如果是,执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry,然后保存到一个集合用于在执行完所有的BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry方法之后,再执行BeanFactoryPostProcessor.postProcessBeanFactory。

1     public static voidinvokeBeanFactoryPostProcessors(2             ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor>beanFactoryPostProcessors) {3
4         //Invoke BeanDefinitionRegistryPostProcessors first, if any.
5         Set<String> processedBeans = new HashSet<String>();6
7         if (beanFactory instanceofBeanDefinitionRegistry) {8             BeanDefinitionRegistry registry =(BeanDefinitionRegistry) beanFactory;9             List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();10             List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
11                     new LinkedList<BeanDefinitionRegistryPostProcessor>();12
13             for(BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {14                 if (postProcessor instanceofBeanDefinitionRegistryPostProcessor) {15                     BeanDefinitionRegistryPostProcessor registryPostProcessor =
16 (BeanDefinitionRegistryPostProcessor) postProcessor;17 registryPostProcessor.postProcessBeanDefinitionRegistry(registry);18 registryPostProcessors.add(registryPostProcessor);19 }20                 else{21 regularPostProcessors.add(postProcessor);22 }23 }24
25             //Do not initialize FactoryBeans here: We need to leave all regular beans26             //uninitialized to let the bean factory post-processors apply to them!27             //Separate between BeanDefinitionRegistryPostProcessors that implement28             //PriorityOrdered, Ordered, and the rest.
29             String[] postProcessorNames =
30                     beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);31
32             //First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
33             List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();34             for(String ppName : postProcessorNames) {35                 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {36                     priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));37 processedBeans.add(ppName);38 }39 }40 sortPostProcessors(beanFactory, priorityOrderedPostProcessors);41 registryPostProcessors.addAll(priorityOrderedPostProcessors);42 invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);43
44             //Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
45             postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);46             List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();47             for(String ppName : postProcessorNames) {48                 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {49                     orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));50 processedBeans.add(ppName);51 }52 }53 sortPostProcessors(beanFactory, orderedPostProcessors);54 registryPostProcessors.addAll(orderedPostProcessors);55 invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);56
57             //Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
58             boolean reiterate = true;59             while(reiterate) {60                 reiterate = false;61                 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);62                 for(String ppName : postProcessorNames) {63                     if (!processedBeans.contains(ppName)) {64                         BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);65 registryPostProcessors.add(pp);66 processedBeans.add(ppName);67 pp.postProcessBeanDefinitionRegistry(registry);68                         reiterate = true;69 }70 }71 }72
73             //Now, invoke the postProcessBeanFactory callback of all processors handled so far.
74 invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);75 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);76 }77
78         else{79             //Invoke factory processors registered with the context instance.
80 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);81 }82
83         //Do not initialize FactoryBeans here: We need to leave all regular beans84         //uninitialized to let the bean factory post-processors apply to them!
85         String[] postProcessorNames =
86                 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);87
88         //Separate between BeanFactoryPostProcessors that implement PriorityOrdered,89         //Ordered, and the rest.
90         List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();91         List<String> orderedPostProcessorNames = new ArrayList<String>();92         List<String> nonOrderedPostProcessorNames = new ArrayList<String>();93         for(String ppName : postProcessorNames) {94             if(processedBeans.contains(ppName)) {95                 //skip - already processed in first phase above
96 }97             else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {98                 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));99 }100             else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {101 orderedPostProcessorNames.add(ppName);102 }103             else{104 nonOrderedPostProcessorNames.add(ppName);105 }106 }107
108         //First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
109 sortPostProcessors(beanFactory, priorityOrderedPostProcessors);110 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);111
112         //Next, invoke the BeanFactoryPostProcessors that implement Ordered.
113         List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();114         for(String postProcessorName : orderedPostProcessorNames) {115             orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));116 }117 sortPostProcessors(beanFactory, orderedPostProcessors);118 invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);119
120         //Finally, invoke all other BeanFactoryPostProcessors.
121         List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();122         for(String postProcessorName : nonOrderedPostProcessorNames) {123             nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));124 }125 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);126
127         //Clear cached merged bean definitions since the post-processors might have128         //modified the original metadata, e.g. replacing placeholders in values...
129 beanFactory.clearMetadataCache();130     }

  invokeBeanFactoryPostProcessors方法里会找出所有的bean,先排序然后再执行相应的方法。从源码可以看得出,先执行的是传进来的BeanFactoryPostProcessor,第二是实现了PriorityOrdered的接口,第三是实现了Ordered接口,最后的就是没有指定顺序的,而实现了BeanDefinitionRegistryPostProcessor的,会先执行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry。

  至此,spring对BeanFactoryPostProcessor的扩展点已处理完,从源码可以开出,BeanFactoryPostProcessor的处理会触发bean的创建。

转载于:https://www.cnblogs.com/hanjiehu/p/8671300.html

spring源码阅读(3)-- 容器启动之BeanFactoryPostProcessor相关推荐

  1. Spring源码分析2 — 容器启动流程

    1 主要类 部署web应用时,web容器(比如Tomcat)会读取配置在web.xml中的监听器,从而启动spring容器.有了spring容器之后,我们才能使用spring的IOC AOP等特性.弄 ...

  2. 【Spring 源码阅读】Spring IoC、AOP 原理小总结

    Spring IoC.AOP 原理小总结 前言 版本约定 正文 Spring BeanFactory 容器初始化过程 IoC 的过程 bean 完整的创建流程如下 AOP 的过程 Annotation ...

  3. Spring源码阅读之bean对象的创建过程

    Spring源码阅读之bean对象的创建过程 ​ Spring是通过IOC容器来管理对象的,该容器不仅仅只是帮我们创建了对象那么简单,它负责了对象的整个生命周期-创建.装配.销毁.这种方式成为控制反转 ...

  4. Spring源码阅读(一)——整体结构

    Spring 总共大约有20个模块,由1300多个不同的文件构成. Spring源码阅读可以分为三个路线:IOC,AOP,外部组件. 个人主页:tuzhenyu's page 原文地址:Spring源 ...

  5. 12.源码阅读(app启动流程-android api 26)

    activity的启动流程之前已经通过源码了解了,那么app的启动流程是怎样的,从我们按下app的图标,到应用启动起来显示出画面,中间都经历了什么? 安卓是基于java的,所以和java有一定的相似性 ...

  6. Spring源码阅读 源码环境搭建(一)

    ring 源码阅读的搭建(一) 一 下载spring源码 进入官方网页:https://spring.io/projects/spring-framework 进入相关的github位置,下载zip包 ...

  7. spring 源码阅读笔记-从浅到深的解析

    目录 第一章 源码安装 文章目录 目录 前言 一.spring源码下载 二.构建源码及使用 1.源码构建 2.使用构建源码 总结 前言 由于spring的源码常常以语言和高深莫测的地位存在,而源码解析 ...

  8. spring 源码阅读入门

    spring和源码3.0.5下载 http://download.csdn.net/download/haluoyimo/7752753 http://pan.baidu.com/s/1qYnK784 ...

  9. spring源码阅读--aop实现原理分析

    aop实现原理简介 首先我们都知道aop的基本原理就是动态代理思想,在设计模式之代理模式中有介绍过这两种动态代理的使用与基本原理,再次不再叙述. 这里分析的是,在spring中是如何基于动态代理的思想 ...

最新文章

  1. html float作用,CSS float相关详解
  2. 【SpringBoot零基础案例04】【IEDA 2021.1】SpringBoot核心配置文件appilcation.yml或application.yaml
  3. java soap 头_如何在Java中添加Soap标头
  4. Exchange server 2013(十四)WSUS部署及组策略设置(2)
  5. 万年自学党聊聊如何选择编程学习资源?
  6. python pdf表格识别不出来_Python识别pdf表格
  7. c# LINQ 使用
  8. MySQL之四种SQL性能分析工具
  9. Unity Excel转json且自动生成C#脚本
  10. Linux 虚拟机内挂载 iso 文件
  11. Prolog编程学习(一)
  12. 美创科技出席世界信息安全大会:多维数据安全框架体系,护航新基建发展
  13. 分布式系统-共识协议
  14. matlab画红色爱心(心形图)
  15. 低版本浏览器(chrome小于40 firefox小于50 ie小于9)会提示升级信息
  16. 印度舞曲吉米来吧(中文版)铃声 印度舞曲吉米来吧(中文版)手机...
  17. UE4中三维几何总结——几何学基础
  18. pyinstaller打包exe加入版本和版权信息
  19. 商业研究(19):变革家,专注创业项目分析,重点服务广大散户(建议股权众筹者谨慎买入。。。)
  20. 【限时删】刘*55页ppt大瓜,比项*醒的还要精彩!

热门文章

  1. 社交网络+大数据真的用来可以模拟一个活人吗?
  2. SpringCloud运行时刷新数据源相关配置
  3. Xcode8注释有时会失效的解决方法
  4. 转:http2.0时代即将到来~~~~~
  5. 那些帮助你成为优秀前端工程师的讲座——《性能篇》
  6. 基本设计模式:单例模式和工厂模式代码实现
  7. 经典英语口语,不得不看(推荐)
  8. 主机动手系列 — 怎么管理Suse Linux
  9. another rejection from Cambridge MPhil in Management
  10. C++二维数组名的再探索