前言

  • 上篇博客spring 5.0.x源码学习系列四: AnnotationConfigApplicationContext类register办法作用次要介绍了register办法的作用。上面咱们将进入初始化spring环境最重要的一步:refresh办法

一、refresh源码黑箱实践

  • 在此篇章中,咱们先把源码中每个办法的执行流程先列进去, 再依据每一个具体的办法进行解析
  • 源码

        @Override    public void refresh() throws BeansException, IllegalStateException {        synchronized (this.startupShutdownMonitor) {            // Prepare this context for refreshing.            prepareRefresh();            // 获取spring bean工厂            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();            // Prepare the bean factory for use in this context.            // 这个办法执行实现, spring的bean单例容器中会存在三个bean,            // 别离是systemEnvironment, environment, systemProperties            // 同时会增加ApplicationContextAwareProcessor的后置处理器, 这个处理器没有走            // spring的bean初始化, 是在外部间接new进去的, 该处理器是用来解决实现了            // ApplicationContextAware接口的bean, 调用重写的set办法, 所以能够利用            // 这种办法获取spring的上下文对象            prepareBeanFactory(beanFactory);            try {                // 该办法没有做任何事, 外部无任何逻辑                postProcessBeanFactory(beanFactory);                // 调用后置处理器, 此办法太重要了, 在后续的源码解读系列中会解析它                // 先大抵总结下它做了什么事                // 1. 解决手动增加的BeanFactoryPostProcessor                //   1.1 调用手动增加的BeanDefinitionRegistryPostProcessor, 并增加到存储它的汇合中,                //       该汇合名字为: registryProcessors                //   1.2 存储手动增加的BeanFactoryPostProcessor,                //       该汇合名字为: regularPostProcessors                //   留神: 下面这个步骤是if else逻辑, 存了一个另外一个就不会存了                // 2. 执行BeanDefinitionRegistryPostProcessor类型且实现了PriorityOrdered接                //    口的后置处理器. 默认执行spring内置BeanDefinitionRegistryPostProcessor                //    后置处理器(ConfigurationClassPostProcessor), 这个后置处理器执行完之后,                //    所有能被扫描进去的bean都以BeanDefinition的形式注册到bean工厂了                // 3. 执行BeanDefinitionRegistryPostProcessor类型且实现了                //    Ordered接口的后置处理器                // 4. 执行以@Component形式增加的BeanDefinitionRegistryPostProcessor类型没实现                //    Ordered和PriorityOrdered接口的后置处理器                // 5. 执行regularPostProcessors和registryProcessors数据结构中                //    BeanFactoryPostProcessor类型的后置处理器(在此处执行                //    ConfigurationClassPostProcessor类的postProcessBeanFactory办法, 次要是                //    为全配置类生成了cglib代理类的Class对象, 并批改它的beanDefinition信息为代                //    理类的信息                // 6. 执行以@Component模式增加并实现了PriorityOrdered接口的BeanFactoryPost                //    Processor后置处理器                // 7. 执行以@Component模式增加并实现了Ordered接口的BeanFactoryPost                //    Processor后置处理器                // 8. 执行以@Component模式增加并未实现PriorityOrdered和Ordered接口的Bean                //    FactoryPostProcessor后置处理器                invokeBeanFactoryPostProcessors(beanFactory);                // 注册spring bean工厂的BeanPostProcessor                // 其中包含spring内置的、扫描进去的(eg: 应用ImportBeanDefinitionRegistrar, AOP的实现形式)、                // 本人手动增加的(手动增加BeanDefinitionRegistryPostProcessor,                // 并在其中注册一个BeanPostProcessor的bean)                //                // 默认状况下, spring内置的3个BeanPostProcessor别离为:                //   org.springframework.context.annotation.internalAutowiredAnnotationProcessor   => 解决@Autowired注解的                //   org.springframework.context.annotation.internalRequiredAnnotationProcessor  => 解决@Required注解的                //   org.springframework.context.annotation.internalCommonAnnotationProcessor  => 解决Common注解的后置处理器                // 以及各种实现了PriorityOrdered接口、Ordered接口的BeanPostProcessor解决                // 最次要的就是把这些bean通过spring bean工厂创立进去, 并增加到一个寄存BeanPostProcessor的list中, 再利用播送                // 机制调用                // 我感觉这里用list而不必set的起因有两个                // 1. list是有序的, 因为有些BeanPostProcessor会实现PriorityOrdered接口、Ordered接口, 所以要依照肯定的程序执行                // 2. 播送机制时要遍历汇合, list遍历速度快一些                registerBeanPostProcessors(beanFactory);                // Initialize message source for this context.                // 国际化                initMessageSource();                // Initialize event multicaster for this context.                // 初始化spring事件驱动模型的执行者                initApplicationEventMulticaster();                // 该办法没有做任何事, 外部无任何逻辑                onRefresh();                // 注册本人手动增加的监听器和spring扫描进去的监听器                // 手动增加的监听器: 调用spring上下文的addApplicationListener办法, eg: AnnotationConfigApplicationContext上下文的办法                // spring扫描进去的监听器: 有@Component注解标识的监听器                // 这里有人会问: 万一我一个监听器同时加了@Component注解也手动调用了addApplicationListener增加呢?                // 没关系, 那就执行两次呗, 因为spring解决手动增加的和扫描进去的监听器是不一样的, 手动增加的是一个java 对象, 而spring扫描进去                // 的监听器是一个bean, 所以这两个监听器是同一类型的不同对象                // 但要留神的是, 手动增加的监听器是一个java object, 而spring扫描进去的是一个bean                registerListeners();                // 开始创立非形象、非原型、非懒加载的bean 以及解决bean的主动拆卸                finishBeanFactoryInitialization(beanFactory);                // 实现刷新, 公布相应的事件                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();            }        }    }    
  • 总结

    1. 由源码中的正文可知: refresh办法次要做的就是填充spring的整个bean环境(之前的spring环境都是空壳), 包含扫描bean,初始化非形象、单例、非懒加载的bean, 以及初始化spring事件驱动模型。
    2. 这里提供下spring 上下文环境的图, 不便了解大抵构造

二、本篇博客的配角: invokeBeanFactoryPostProcessor办法

  • 流程图
  • 源码正文

        public static void invokeBeanFactoryPostProcessors(               ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {          // Invoke BeanDefinitionRegistryPostProcessors first, if any.       Set<String> processedBeans = new HashSet<>();       // 传入的bean工厂DefaultListableBeanFactory也是一个BeanDefinitionRegistry, 它实现了这个接口       if (beanFactory instanceof BeanDefinitionRegistry) {           BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;           // 用来存储手动增加BeanFactoryPostProcessor的处理器,           // eg: context.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());           // 其中context是AnnotationConfigApplicationContext对象, 然而它只是执行到了父类AbstractApplicationContext的办法           List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();           // 用来存储手动增加BeanDefinitionRegistryPostProcessor的处理器, 也是执行上述正文中说的办法           // 因为BeanFactoryPostProcessor有一个子类叫BeanDefinitionRegistryPostProcessor           // regularPostProcessors和registryProcessors这两个list只是为了存储手动增加的BeanFactoryPostProcessor           List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();           for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {               if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {                   BeanDefinitionRegistryPostProcessor registryProcessor =                           (BeanDefinitionRegistryPostProcessor) postProcessor;                   // 对于手动增加的BeanDefinitionRegistryPostProcessor会在这里第一次被调用, 所以这里是后置处理器第一次被调用的中央                   registryProcessor.postProcessBeanDefinitionRegistry(registry);                   // 存储手动增加的BeanDefinitionRegistryPostProcessor, 后续会用到                   registryProcessors.add(registryProcessor);               }               else {                   // 存储手动增加的BeanFactoryPostProcessor, 后续会用到                   regularPostProcessors.add(postProcessor);               }           }           // 这个list是用来存储spring内置的BeanFactoryPostProcessor           List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();           // 这里是调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor后置处理器           // 这里只是获取, 调用是在上面的invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);实现的           String[] postProcessorNames =                   beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);           for (String ppName : postProcessorNames) {               if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {                   currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                   processedBeans.add(ppName);               }           }           sortPostProcessors(currentRegistryProcessors, beanFactory);           registryProcessors.addAll(currentRegistryProcessors);           // 这里首先调用的类是spring内置beanName叫org.springframework.context.annotation.internalConfigurationAnnotationProcessor,           // 类名叫ConfigurationClassPostProcessor的bean           // 因为在spring内置的6个bean中只有它是实现了BeanDefinitionRegistryPostProcessor接口           // 所以ConfigurationClassPostProcessor类这一次被调用的次要目标是:           // 1. 为bean工厂生成factoryId并记录起来           // 2. 循环解析传入的配置类(即传入register办法中的几个Class类对应的类)           //  2.1 依据类获取他们的BeanDefinition, 来判断BeanDefinition是否为AnnotatedBeanDefinition类型(因为目前是思考java config模式, 所以只思考这种类型)           //  2.2 判断传入类是否加了@Configuration注解或者(@Component和@ComponentScan和@Import和ImportResource注解)或者外部是否有办法增加了@Bean注解并解析他们           invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);           currentRegistryProcessors.clear();           // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.           postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);           for (String ppName : postProcessorNames) {               if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {                   currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                   processedBeans.add(ppName);               }           }           sortPostProcessors(currentRegistryProcessors, beanFactory);           registryProcessors.addAll(currentRegistryProcessors);           invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);           currentRegistryProcessors.clear();           // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.           boolean reiterate = true;           while (reiterate) {               reiterate = false;               postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);               for (String ppName : postProcessorNames) {                   if (!processedBeans.contains(ppName)) {                       currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));                       processedBeans.add(ppName);                       reiterate = true;                   }               }               sortPostProcessors(currentRegistryProcessors, beanFactory);               registryProcessors.addAll(currentRegistryProcessors);               invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);               currentRegistryProcessors.clear();           }           // Now, invoke the postProcessBeanFactory callback of all processors handled so far.           // 这里是第一次调用手动增加到spring的BeanDefinitionRegistryPostProcessor的重写BeanFactoryPostProcessors接口的(postProcessBeanFactory)办法           // 因为BeanDefinitionRegistryPostProcessor是继承BeanFactoryPostProcessor类。所以也重写了BeanFactoryPostProcessor的办法           // 在第一次调用时只调用了BeanDefinitionRegisterPostProcessor中的办法           invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);           // 这里是第一次调用手动增加到spring的BeanFactoryPostProcessor           invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);       }       else {           // Invoke factory processors registered with the context instance.           invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);       }       // Do not initialize FactoryBeans here: We need to leave all regular beans       // uninitialized to let the bean factory post-processors apply to them!       // 这里是调用非手动增加的BeanFactoryPostProcessor后置处理器, 即应用了@Component注解       // 因为在上一步调用ConfigurationClassPostProcessor这种类型(BeanDefinitionRegistryBeanFactory)的后置处理器时, 对包曾经扫描胜利,       // 并将扫描进去的类信息封装成ScannedGenericBeanDefinition的BeanDefinition了, 所以依据类型找出的来的bean包含以注解的形式注册的       // BeanFactoryPostProcessor,但也包含ConfigurationClassPostProcessor, 因为它实现的BeanDefinitionRegistryBeanFactory接口也       // 继承了BeanFactoryPostProcessor接口       String[] postProcessorNames =               beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);       // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,       // Ordered, and the rest.       List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();       List<String> orderedPostProcessorNames = new ArrayList<>();       List<String> nonOrderedPostProcessorNames = new ArrayList<>();       for (String ppName : postProcessorNames) {           if (processedBeans.contains(ppName)) {               // skip - already processed in first phase above           }           else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {               priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));           }           else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {               orderedPostProcessorNames.add(ppName);           }           else {               nonOrderedPostProcessorNames.add(ppName);           }       }       // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.       // 解析实现了PriorityOrdered接口的BeanFactoryPostProcessor并按程序执行       sortPostProcessors(priorityOrderedPostProcessors, beanFactory);       invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);       // 解析实现了Ordered接口的BeanFactoryPostProcessor并按程序执行       List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();       for (String postProcessorName : orderedPostProcessorNames) {           orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));       }       sortPostProcessors(orderedPostProcessors, beanFactory);       invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);       // 调用实现了没有实现PriorityOrdered和Ordered接口的BeanFactoryPostProcessor的后置处理器       List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();       for (String postProcessorName : nonOrderedPostProcessorNames) {           nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));       }       invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);       // Clear cached merged bean definitions since the post-processors might have       // modified the original metadata, e.g. replacing placeholders in values...       beanFactory.clearMetadataCache();   }

三、我的项目测试demo

3.1 我的项目构造

3.1.1 构造全景图

3.1.2 各类详情与作用

  1. 我的项目入口(启动spring环境的入口)
  2. 全配置类, 定义扫描的包
  3. 手动增加的BeanDefinitionRegistryPostProcessor
  4. 手动增加的BeanFactoryPostProcessor
  5. 由spring扫描进去的BeanDefinitionRegistryPostProcessor但无实现Ordered和PriorityOrdered接口
  6. 由spring扫描进去的BeanDefinitionRegistryPostProcessor实现了Ordered接口, 且权重为1 => 权重低, 优先执行
  7. 由spring扫描进去的BeanDefinitionRegistryPostProcessor实现了Ordered接口, 且权重为2 => 权重低, 优先执行
  8. 由spring扫描进去的BeanDefinitionRegistryPostProcessor实现了PriorityOrdered接口, 且权重为1 => 权重低, 优先执行
  9. 由spring扫描进去的BeanDefinitionRegistryPostProcessor实现了PriorityOrdered接口, 且权重为2 => 权重低, 优先执行
  10. 由spring扫描进去的BeanFactoryPostProcessor
  11. 由spring扫描进去的BeanFactoryPostProcessor实现了Ordered接口, 且权重为1 => 权重越低, 越优先执行
  12. 由spring扫描进去的BeanFactoryPostProcessor实现了Ordered接口, 且权重为2 => 权重越低, 越优先执行
  13. 由spring扫描进去的BeanFactoryPostProcessor实现了PriorityOrdered接口, 且权重为1 => 权重越低, 越优先执行
  14. 由spring扫描进去的BeanFactoryPostProcessor实现了PriorityOrdered接口, 且权重为2 => 权重越低, 越优先执行

3.2 执行流程及原理

3.2.1 解决手动增加的BeanFactoryPostProcessor(蕴含BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor)

![在这里插入图片形容](https://img-blog.csdnimg.cn/20200103111936684.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2F2ZW5nZXJFdWc=,size_16,color_FFFFFF,t_70)

3.2.2 执行BeanDefinitionRegistryPostProcessor类型且实现了PriorityOrdered接口的后置处理器

此步骤十分重要,后续将专门为此步骤总结一篇博客, 来具体形容它做了些什么事

![在这里插入图片形容](https://img-blog.csdnimg.cn/20200103115225373.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2F2ZW5nZXJFdWc=,size_16,color_FFFFFF,t_70)

3.2.3 执行BeanDefinitionRegistryPostProcessor类型且实现了Ordered接口的后置处理器, 执行过程与第二步大同小异

3.2.4 执行BeanDefinitionRegistryPostProcessor类型且未实现Ordered接口和PriorityOrdered接口的后置处理器, 执行过程与第三步大同小异

3.2.5 解决BeanDefinitionRegistryPostProcessor类型的BeanFactoryPostProcessor

  • 上述4步都是调用BeanDefinitionRegistryPostProcessor类型的后置处理器, 前面将开始调用BeanFactoryPostProcessor类型的后置处理器。因为还有手动增加BeanDefinitionRegistryPostProcessor也是BeanFactoryPostProcessor类型的后置处理器(继承), 所以此步骤将开始调用手动增加的BeanDefinitionRegistryPostProcessor后置处理器的BeanFactoryPostProcessor中的办法以及手动增加的BeanFactoryPostProcessor

     // Now, invoke the postProcessBeanFactory callback of all processors handled so far. // 这里是第一次调用手动增加到spring的BeanDefinitionRegistryPostProcessor的重写BeanFactoryPostProcessors接口的(postProcessBeanFactory)办法 // 因为BeanDefinitionRegistryPostProcessor是继承BeanFactoryPostProcessor类。所以也重写了BeanFactoryPostProcessor的办法 // 在第一次调用时只调用了BeanDefinitionRegisterPostProcessor中的办法 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); // 这里是第一次调用手动增加到spring的BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

3.2.6 执行以@Component模式增加并实现了PriorityOrdered接口的BeanFactoryPostProcessor后置处理器

3.2.7 执行以@Component模式增加并实现了Ordered接口的BeanFactoryPostProcessor后置处理器

3.3 对于"3.2.3 执行BeanDefinitionRegistryPostProcessor类型且实现了Ordered接口的后置处理器, 执行过程与第二步大同小异"的两个疑难

  • 原图
问题答案
Q1: 为什么这里也执行了实现PriorityOrdered接口的后置处理器?下面不是曾经执行过了吗?因为PriorityOrdered接口继承了Ordered接口, 所以在解决实现Ordered类型的接口时, 也会把实现PriorityOrdered接口的后置处理器也拿进去。同时之前确实曾经执行过了实现了PriorityOrdered接口的后置处理器(ConfigurationClassPostProcessor), 但这是一个非凡的后置处理器, 因为它,咱们能力在前面获取@Component注解模式增加的后置处理器。最重要的是在执行它的时候, bean工厂中只有一个实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor类型的后置处理器, 所以spring才用了processedBeans的set汇合来存储曾经执行过的后置处理器
Q2: 为什么只执行了postProcessorNames的2,3,4,5下标的后置处理器?因为它们都实现了Ordered接口, 只管有些后置处理器实现的是PriorityOrdered接口, 但PriorityOrdered接口继承了Ordered接口

三、小结

  • invokeBeanFactoryPostProcessor办法的次要作用就是调用后置处理器, 这里最须要次要到的一个后置处理器就是ConfigurationClassPostProcessor, 它不仅做了扫描工作还做了为全配置类生成cglib代理对象的工作(因为它有两个身份: 一个是BeandefinitionRegistryPostProcessor另一个是BeanFactoryPostProcessor)
  • 对于BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor后置处理器的区别和作用

    类型提供api作用
    BeanDefinitionRegistryPostProcessorBeanDefinitionRegistry是一个beanDefinition的注册器, 个别用它来注册一个beanDefinition
    BeanFactoryPostProcessorConfigurableListableBeanFactory其实就是spring的bean工厂, 只不过是用父类来接管。 bean工厂都能够拿到了, 咱们能够对bean做不可形容的事件了,比方扭转bean的class为它创立代理对象,
  • 应用 BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor后置处理器的注意事项

    • 得明确每个后置处理器的执行程序 eg:手动增加的BeanDefinitionRegistryPostProcessor类型的后置处理器, 比spring内置和以@Component形式增加的后置处理器都先执行
    • 相熟实现不同接口的后置处理器的执行程序, eg: BeanDefinitionRegistryPostProcessorBeanFactoryPostProcessor类型的后置处理器都是优先解决实现PriorityOrdered接口
  • spring源码学习对应GitHub 地址https://github.com/AvengerEug/spring/tree/develop/resourcecode-study
  • I am a slow walker, but I never walk backwards.