zoukankan      html  css  js  c++  java
  • Spring源码BeanFactoryPostProcessor和BeanPostProcessor机制

      两者都是后置处理器,一个是针对BeanFactory,也就是对象工厂,一个是针对Bean,也就是容器中的对象。后置处理器的作用就是处理一些创建完成之后的操作,比如BeanFactoryPostProcessor 用于动态的向容器注册一些Bean; BeanPostProcessor 用于扩展Bean,比如AOP的动态代理对象的替换就是在BeanPostProcessor 中完成的。

    1. BeanFactoryPostProcessor 创建以及调用时机

      以Mybatis的org.mybatis.spring.mapper.MapperScannerConfigurer  为模板进行参考,编写自己的BeanFactoryPostProcessor。

     1.  MyBeanFactoryPostProcessor

    package cn.qz.dubbo;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionBuilder;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    import org.springframework.stereotype.Component;
    
    @Component
    public class MyBeanFactoryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    
        public MyBeanFactoryPostProcessor() {
            System.out.println("000000");
        }
    
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
            System.out.println("111222");
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(MyBeanFactoryPostProcessor2.class.getName());
            beanDefinitionRegistry.registerBeanDefinition("myBeanFactoryPostProcessor2", beanDefinitionBuilder.getBeanDefinition());
        }
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
            System.out.println("222333");
        }
    }

    2. MyBeanFactoryPostProcessor2

    package cn.qz.dubbo;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    
    public class MyBeanFactoryPostProcessor2 implements BeanDefinitionRegistryPostProcessor {
    
        public MyBeanFactoryPostProcessor2() {
            System.out.println("MyBeanFactoryPostProcessor2 000000");
        }
    
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
            System.out.println("MyBeanFactoryPostProcessor2 111222");
        }
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
            System.out.println("MyBeanFactoryPostProcessor2 222333");
        }
    }

    3. 测试如下:

    这里只输出两个后置处理器的输出结果:

    000000
    111222
    MyBeanFactoryPostProcessor2 000000
    MyBeanFactoryPostProcessor2 111222
    222333
    MyBeanFactoryPostProcessor2 222333

      可以看到上面的过程为:MyBeanFactoryPostProcessor()-》MyBeanFactoryPostProcessor#postProcessBeanDefinitionRegistry -》 MyBeanFactoryPostProcessor2() -》MyBeanFactoryPostProcessor2#postProcessBeanDefinitionRegistry -》 MyBeanFactoryPostProcessor#postProcessBeanFactory -》 MyBeanFactoryPostProcessor2#postProcessBeanFactory

    4. 源码研究

    (0) springboot 项目注解启动使用的ApplicationContext 是org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext

    1》构造方法:org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext#AnnotationConfigServletWebServerApplicationContext()

        public AnnotationConfigServletWebServerApplicationContext() {
            this.annotatedClasses = new LinkedHashSet();
            this.reader = new AnnotatedBeanDefinitionReader(this);
            this.scanner = new ClassPathBeanDefinitionScanner(this);
        }

    2》在创建reader 的过程中有重要的一步:

    org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(org.springframework.beans.factory.support.BeanDefinitionRegistry)

        public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
            this(registry, getOrCreateEnvironment(registry));
        }
        public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            Assert.notNull(environment, "Environment must not be null");
            this.registry = registry;
            this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
            AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
        }

    3》 调用工具类注册 AnnotationConfigProcessors, 也就是配置的前置处理器

    org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry)

        public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
            registerAnnotationConfigProcessors(registry, null);
        }

    org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)

        public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
                BeanDefinitionRegistry registry, @Nullable Object source) {
    
            DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
            if (beanFactory != null) {
                if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                    beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
                }
                if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                    beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
                }
            }
    
            Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    
            if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
            if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
            if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition();
                try {
                    def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                            AnnotationConfigUtils.class.getClassLoader()));
                }
                catch (ClassNotFoundException ex) {
                    throw new IllegalStateException(
                            "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
                }
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
            }
    
            if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
            }
    
            if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
                RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
                def.setSource(source);
                beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
            }
    
            return beanDefs;
        }

      这里有重要的一步就是注册了ConfigurationClassPostProcessor 对象。ConfigurationClassPostProcessor 对象实现了BeanDefinitionRegistryPostProcessor 接口,是一个对象工厂后置处理器。用于处理所有的@Configuration、@Import、@Component 等注解注册的对象。

    (1) org.springframework.context.support.AbstractApplicationContext#refresh 标记源码的开始

        @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                // Prepare this context for refreshing.
                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();
                }
            }
        }

    (2) invokeBeanFactoryPostProcessors    方法处理BeanFactory后置处理器的逻辑

    org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors

        protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
            PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    
            // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
            // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
            if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
            }
        }

    (3) org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

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

    1》 if (beanFactory instanceof BeanDefinitionRegistry) 代码块判断工厂类型是BeanDefinitionRegistry, 工厂类型是: org.springframework.beans.factory.support.DefaultListableBeanFactory, 所以返回是true

    2》12-22 行代码先处理 registryProcessor.postProcessBeanDefinitionRegistry 方法, 也就是直接注册到 org.springframework.context.support.AbstractApplicationContext#beanFactoryPostProcessors  属性上的后置处理器

    3》28-42 行代码的逻辑实际是处理上面的 org.springframework.context.annotation.ConfigurationClassPostProcessor, 也就是动态的注册bean。处理完之后清空currentRegistryProcessors, 并将处理过的ConfigurationClassPostProcessor 加入到 registryProcessors 标记处理过

    4》44-55行代码处理实现了BeanDefinitionRegistryPostProcessor 接口和Ordered 接口的后置处理器

    5》57-77行处理所有没有处理过的BeanDefinitionRegistryPostProcessor 后置处理器, 获取到的后置处理器如下:

       serviceAnnotationBeanPostProcessor 是dubbo的一个对象后置处理器。myBeanFactorypostProcessor 是我们自己创建的一个后置处理器。然后调用getBean 进行创建对象,接下来加入到currentRegistryProcessors, 然后调用org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors 进行处理后置处理器(只对currentRegistryProcessors 集合中的处理,也就是没有处理过的):

        private static void invokeBeanDefinitionRegistryPostProcessors(
                Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    
            for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
                postProcessor.postProcessBeanDefinitionRegistry(registry);
            }
        }

      处理完成之后清空currentRegistryProcessors, 并且将处理过的加入registryProcessors。

    注意: 这里有个循环的逻辑reiterate, 默认是false, 当本轮循环有处理的就将reiterate 设为true。 因为调用后置处理器的方法的时候有可能动态的注册 BeanFactoryPostProcessor, 所以需要处理完一遍之后再次循环遍历拿容器中的对象进行判断,如果有未处理过的就调用postProcessBeanDefinitionRegistry。 否则就结束循环。

      然后调用org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors 处理所有处理过的BeanFactoryPostProcessor 对象的postProcessBeanFactory 方法:

        private static void invokeBeanFactoryPostProcessors(
                Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
    
            for (BeanFactoryPostProcessor postProcessor : postProcessors) {
                postProcessor.postProcessBeanFactory(beanFactory);
            }
        }

    这里传入的集合包括的对象有:

     6》85-132 行重新获取容器中所有的BeanFactoryPostProcessor, 然后判断哪些对象没有处理过,会调用org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors 处理未处理过的后置处理器的方法

    2. BeanPostProcessor 创建以及调用时机

      参考: https://www.cnblogs.com/qlqwjy/p/14415269.html 

    【当你用心写完每一篇博客之后,你会发现它比你用代码实现功能更有成就感!】
  • 相关阅读:
    Eclipse Alt + / 无提示
    洛谷 P1101 单词方阵
    力扣题解 7th 整数反转
    力扣题解 344th 反转字符串
    力扣题解 48th 旋转图像
    力扣题解 36th 有效的数独
    力扣题解 1th 两数之和
    力扣题解 283th 移动零
    力扣题解 66th 加一
    力扣题解 350th 两个数组的交集 II
  • 原文地址:https://www.cnblogs.com/qlqwjy/p/15144614.html
Copyright © 2011-2022 走看看