美文网首页
SpringIOC之BeanFactoryPostProcess

SpringIOC之BeanFactoryPostProcess

作者: likly | 来源:发表于2020-10-29 16:43 被阅读0次

    概述

    BeanFactoryPostProcessorSpring提供的扩展接口之一,可用于对容器中的BeanDefinitions进行修改,例如:

    • 向容器中添加新的BeanDefinition;
    • 修改指定的BeanDefiniton;

    定义

    Spring内置了两个后置处理器接口,定义如下:

    • BeanFactoryPostProcessor
    @FunctionalInterface
    public interface BeanFactoryPostProcessor {
    
        /**
         * 在初始化前修改应用上下文 application context's 中所有的 bean 定义。
         */
        void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
    
    }
    
    • BeanDefinitionRegistryPostProcessor
    public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    
        /**
         * 在初始化前修改应用上下文 application context's 中 bean 的注册表。
         */
        void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
    
    }
    

    继承关系如下图所示:

    BeanFactoryPostProcessor

    调用入口

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        // 调用BeanFactoryPostProcessor
        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()));
        }
    }
    

    从上述方法调用可知,Spring通过PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())来调用BeanFactoryPostProcessors,接下来我们就详细来跟进解读下……

    流程详解

    1. 方法声明
    public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    1. 定义processedBeans用于缓存BeanFactoryPostProcessor的名称
    Set<String> processedBeans = new HashSet<>();
    
    1. 判断beanFactory是否是BeanDefinitionRegistry的实例,如果不是,则直接调用,否则分开调用
    if (beanFactory instanceof BeanDefinitionRegistry) {
        ...
    }else {
        // Invoke factory processors registered with the context instance.
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }
    
    1. 3步中,简述了当beanFactory不是BeanDefinitionRegistry的情况,现在来看下当beanFactoryBeanDefinitionRegistry的情况下又是如何执行的呢。
    BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    
    // 遍历beanFactoryPostProcessors
    // a. 如果是BeanDefinitionRegistryPostProcessor,则调用其postProcessBeanDefinitionRegistry方法,并添加到registryProcessors
    // b. 否则,缓存到regularPostProcessors
    for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
        if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
            BeanDefinitionRegistryPostProcessor registryProcessor =
                    (BeanDefinitionRegistryPostProcessor) postProcessor;
            // 调用postProcessBeanDefinitionRegistry
            registryProcessor.postProcessBeanDefinitionRegistry(registry);
            // 添加到registryProcessors
            registryProcessors.add(registryProcessor);
        }
        else {
            // 缓存到regularPostProcessors
            regularPostProcessors.add(postProcessor);
        }
    }
    
    1. 定义一个缓存池currentRegistryProcessors,用于缓存分别实现了PriorityOrderedOrdered接口以及未实现接口的BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    
    1. 调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
    // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    // 调用实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessors
    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);
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    currentRegistryProcessors.clear();
    
    1. 调用实现了Ordered接口的BeanDefinitionRegistryPostProcessor
    // 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();
    
    1. 调用其它BeanDefinitionRegistryPostProcessor
    // 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();
    }
    
    1. 调用BeanDefinitionRegistryPostProcessorpostProcessBeanFactory(beanFactory)方法
    // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    
    1. 至此,当beanFactoryBeanDefinitionRegistry的专有处理流程结束,接下来,我们再继续跟进通用的处理流程。
    // Do not initialize FactoryBeans here: We need to leave all regular beans
    // uninitialized to let the bean factory post-processors apply to them!
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
    1. BeanFactoryPostProcessor按实现了和其它进行分类。
    // 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);
        }
    }
    
    1. 调用实现了PriorityOrdered接口的BeanFactoryPostProcessor
    // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
    1. 调用实现了Ordered接口的BeanFactoryPostProcessor
    // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    for (String postProcessorName : orderedPostProcessorNames) {
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    sortPostProcessors(orderedPostProcessors, beanFactory);
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
    1. 调用其它BeanFactoryPostProcessor
    // Finally, invoke all other BeanFactoryPostProcessors.
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
    1. 清理元数据缓存,至此,SpringBean后置处理器BeanFactoryPostProcessor调用结束。
    // Clear cached merged bean definitions since the post-processors might have
    // modified the original metadata, e.g. replacing placeholders in values...
    beanFactory.clearMetadataCache();
    

    相关文章

      网友评论

          本文标题:SpringIOC之BeanFactoryPostProcess

          本文链接:https://www.haomeiwen.com/subject/rrflvktx.html