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 

 

posted @ 2021-08-15 22:38  QiaoZhi  阅读(225)  评论(0编辑  收藏  举报