1. 程式人生 > 實用技巧 >Spring中處理Bean後置處理器BeanPostProcessor順序以及流程

Spring中處理Bean後置處理器BeanPostProcessor順序以及流程

執行順序

  1. 執行通過ApplicationContext新增進來的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  2. 執行BeanFactory中實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  3. 執行BeanFactory中實現了Ordered介面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()
    方法
  4. 執行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  5. 執行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
  6. 執行通過ApplicationContext新增進來的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  7. 執行BeanFactory中實現了PriorityOrdered介面的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  8. 執行BeanFactory中實現了Ordered介面的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  9. 執行BeanFactory中其他的BeanFactoryPostProcessor的postProcessBeanFactory()方法

簡單概括: Spring保證先執行 postProcessBeanDefinitionRegistry() 方法;

      保證先執行通過手動新增進來的後置處理器,後執行程式碼實現的後置處理器

      BeanDefinitionRegistryPostProcessor優先順序高於BeanFactoryPostProcessor

      手動新增的BeanDefinitionRegistryPostProcessor》實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor》實現了Ordered介面BeanDefinitionRegistryPostProcessor》其他的BeanDefinitionRegistryPostProcessor

      》手動新增的BeanFactoryPostProcessor》實現了PriorityOrdered介面的BeanFactoryPostProcessor》實現了Ordered介面的BeanFactoryPostProcessor》其他的BeanFactoryPostProcessor

程式碼邏輯:

    在Spring原始碼中,

AbstractApplicationContext的invokeBeanFactoryPostProcessors方法,核心原始碼貼出
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // BeanDefinitionRegistryPostProcessor是一個特殊的BeanFactoryPostProcessor,需要先執行postProcessBeanDefinitionRegistry方法
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;

                    registryProcessor.postProcessBeanDefinitionRegistry(registry);

                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            // 儲存當前需要執行的實現了BeanDefinitionRegistryPostProcessor介面的後置處理器
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            // 首先,先執行實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            for (String ppName : postProcessorNames) {
                // 判斷這個類是否還實現了PriorityOrdered介面
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 這裡呼叫了getBean,所以生成一個BeanDefinitionRegistryPostProcessor的bean物件
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 執行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            // 首先,先執行實現了Ordered介面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
            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.
            // 最後,最後其他普通的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法
            boolean reiterate = true;
            // 在一個BeanDefinitionRegistryPostProcessor中可以註冊另一個BeanDefinitionRegistryPostProcessor,所以需要遞迴找出所有的BeanDefinitionRegistryPostProcessor
            // 一個沒有實現PriorityOrdered介面的BeanDefinitionRegistryPostProcessor如果在內部註冊了一個實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor,那麼就是沒有實現PriorityOrdered介面的先執行
            while (reiterate) {
                reiterate = false;
                // 這裡會再一次拿到實現了PriorityOrdered介面或Ordered介面的BeanDefinitionRegistryPostProcessor,所以需要processedBeans進行過濾
                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();
            }

            //至此 所有的BeanFinition都已經註冊完成

      其中,值得一提的是,下面貼出的原始碼:

            // 在一個BeanDefinitionRegistryPostProcessor中可以註冊另一個BeanDefinitionRegistryPostProcessor,所以需要遞迴找出所有的BeanDefinitionRegistryPostProcessor
            // 一個沒有實現PriorityOrdered介面的BeanDefinitionRegistryPostProcessor如果在內部註冊了一個實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor,那麼就是沒有實現PriorityOrdered介面的先執行
            while (reiterate) {
                reiterate = false;
                // 這裡會再一次拿到實現了PriorityOrdered介面或Ordered介面的BeanDefinitionRegistryPostProcessor,所以需要processedBeans進行過濾
                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();
            }

這段程式碼考慮的是:當其餘“優先順序比較高的BeanFactoryPostProcessor”被註冊進BeanFactory以及呼叫的時候,也有可能會在postProcessBeanDefinitionRegistry方法或者postProcessBeanFactory方法中註冊新的BeanDefinitionRegistryPostProcessor,所以使用while迴圈的遞迴操作,找出以後操作中可能存在的新生成的BeanDefinitionRegistryPostProcessor,如果出現,將其註冊到BeanFactory中。