0
点赞
收藏
分享

微信扫一扫

Spring IOC:invokeBeanFactoryPostProcessors调用链

seuleyang 2022-01-27 阅读 60
spring

参考资料

《Spring IoC源码学习:invokeBeanFactoryPostProcessors 详解》

前文:

《Spring IOC:obtainFreshBeanFactory调用链》

写在开头:本文为个人学习笔记,内容比较随意,夹杂个人理解,如有错误,欢迎指正。

目录

一、概述

二、invokeBeanFactoryPostProcessors

        1、getBeanFactoryPostProcessors

        2、invokeBeanFactoryPostProcessors 

三、getBeanFactoryPostProcessors

        1、getBeanFactoryPostProcessors

         2、添加自定义BeanFactoryPostProcessor

三、invokeBeanFactoryPostProcessors

        1、区分BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor

        2、根据优先级实现BeanDefinitionRegistryPostProcessor

        3、实例化剩余BeanDefinitionRegistryPostProcessors与部分BeanFactoryPostProcessor

        4、针对BeanFactoryPostProcessor重复2、3步操作

总结:


​​​​​​​

一、概述

        invokeBeanFactoryPostProcessors方法会实例化和调用所有 BeanFactoryPostProcessor(包括其子类 BeanDefinitionRegistryPostProcessor)。

        BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。

二、invokeBeanFactoryPostProcessors

        2个重要步骤:

        1、getBeanFactoryPostProcessors

                拿到当前应用上下文beanFactoryPostProcessors变量中的值

        2、invokeBeanFactoryPostProcessors 

                实例化并调用所有已注册的BeanFactoryPostProcessor

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    // getBeanFactoryPostProcessors(): 拿到当前应用上下文beanFactoryPostProcessors变量中的值
    // invokeBeanFactoryPostProcessors: 实例化并调用所有已注册的BeanFactoryPostProcessor
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
 

    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

三、getBeanFactoryPostProcessors

        1、getBeanFactoryPostProcessors

        拿到当前应用上下文中已经注册的 BeanFactoryPostProcessor,默认情况下返回为空。

public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    return this.beanFactoryPostProcessors;
}

         2、添加自定义BeanFactoryPostProcessor

        在《Spring IOC:从ContextLoaderListener到AbstractApplicationContext》中介绍的customizeContext方法会通过determineContextInitializerClasses方法读取web.xml中的参数(globalInitializerClasses与contextInitializerClasses),初始化实现了ApplicationContextInitializer接口的类。

        protected void customizeContext(ServletContext sc, ConfigurableWebApplicationContext wac) {
        //获取初始化器类集合
        List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> initializerClasses =
                determineContextInitializerClasses(sc);
 
        for (Class<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerClass : initializerClasses) {
            Class<?> initializerContextClass =
                    GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class);
            if (initializerContextClass != null && !initializerContextClass.isInstance(wac)) {
                throw new ApplicationContextException(String.format(
                        "Could not apply context initializer [%s] since its generic parameter [%s] " +
                        "is not assignable from the type of application context used by this " +
                        "context loader: [%s]", initializerClass.getName(), initializerContextClass.getName(),
                        wac.getClass().getName()));
            }
            //实例化初始化器并添加到集合中
            this.contextInitializers.add(BeanUtils.instantiateClass(initializerClass));
        }
        //排序并执行,编号越小越早执行
        AnnotationAwareOrderComparator.sort(this.contextInitializers);
        for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : this.contextInitializers) {
            initializer.initialize(wac);
        }
    }

    protected List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>>
            determineContextInitializerClasses(ServletContext servletContext) {
 
        List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> classes =
                new ArrayList<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>>();
        //通过<context-param>属性配置globalInitializerClasses获取全局初始化类名
        String globalClassNames = servletContext.getInitParameter(GLOBAL_INITIALIZER_CLASSES_PARAM);
        if (globalClassNames != null) {
            for (String className : StringUtils.tokenizeToStringArray(globalClassNames, INIT_PARAM_DELIMITERS)) {
                classes.add(loadInitializerClass(className));
            }
        }
        //通过<context-param>属性配置contextInitializerClasses获取容器初始化类名
        String localClassNames = servletContext.getInitParameter(CONTEXT_INITIALIZER_CLASSES_PARAM);
        if (localClassNames != null) {
            for (String className : StringUtils.tokenizeToStringArray(localClassNames, INIT_PARAM_DELIMITERS)) {
                classes.add(loadInitializerClass(className));
            }
        }
 
        return classes;
    }

    @SuppressWarnings("unchecked")
    private Class<ApplicationContextInitializer<ConfigurableApplicationContext>> loadInitializerClass(String className) {
    try {
        // 实例化className
        Class<?> clazz = ClassUtils.forName(className, ClassUtils.getDefaultClassLoader());
        if (!ApplicationContextInitializer.class.isAssignableFrom(clazz)) {
            // 校验clazz是否实现了ApplicationContextInitializer接口, 如果没有则抛异常
            throw new ApplicationContextException(
                    "Initializer class does not implement ApplicationContextInitializer interface: " + clazz);
        }
        // clazz强转成ApplicationContextInitializer, 并返回
        return (Class<ApplicationContextInitializer<ConfigurableApplicationContext>>) clazz;
    } catch (ClassNotFoundException ex) {
        throw new ApplicationContextException("Failed to load context initializer class [" + className + "]", ex);
    }
}

         我们通过新建一个ApplicationContextInitializer的实现类并重写initialize方法实现个性化逻辑,在其中手动添加继承了BeanFactoryPostProcessor接口的MyBeanFactoryPostProcessor。并通过globalInitializerClasses将其注册到上下文中,就可以实现beanFactoryPostProcessors的预存功能。

public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>
{

    public void initialize(ConfigurableApplicationContext applicationContext) {
        MyBeanFactoryPostProcessor myBeanFactoryPostProcessor = new MyBeanFactoryPostProcessor();
        applicationContext.addBeanFactoryPostProcessor(myBeanFactoryPostProcessor);
        System.out.println("将自定义的MyBeanFactoryPostProcessor添加到应用上下文中");
    }
}
<context-param>
    <param-name>globalInitializerClasses</param-name>
    <param-value>
        com.test.MyApplicationContextInitializer
    </param-value>
</context-param>

        

三、invokeBeanFactoryPostProcessors

        首先要介绍下BeanFactoryPostProcessor及其子类BeanDefinitionRegistryPostProcessor。

        BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 时对外暴露的扩展点,Spring IoC 容器允许 BeanFactoryPostProcessor 在容器实例化任何 bean 之前读取 bean 的定义,并可以修改它。

        BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的优先级,主要用来在常规的BeanFactoryPostProcessor 检测开始之前执行。特别是,你可以通过BeanDefinitionRegistryPostProcessor来注册一些常规的BeanFactoryPostProcessor。因为此时所有常规的 BeanFactoryPostProcessor都还没开始被处理。

        对于BeanFactoryPostProcessor的介绍可以看我之前写的文章《传送门》

        由于invokeBeanFactoryPostProcessors整段代码较长,这里按照执行步骤拆分成了几段,如下图所示。

public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    1、区分BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor
    2、根据优先级实现BeanDefinitionRegistryPostProcessor
    3、实例化剩余BeanDefinitionRegistryPostProcessors与部分BeanFactoryPostProcessor
    4、针对BeanFactoryPostProcessor重复2、3步操作
}

        1、区分BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor

             遍历入参beanFactoryPostProcessors,并区分开BeanDefinitionRegistryPostProcessor与BeanFactoryPostProcessor,前者比后者多一步直接执行其postProcessBeanDefinitionRegistry方法,然后分别存入registryProcessors 与regularPostProcessors中。

        注意:这里存储和实现的是作为参数传的beanFactoryPostProcessors,即我们在前文中介绍的利用ApplicationContextInitializer拓展实现的BeanFactoryPostProcessor,不包括在容器中注册的BeanFactoryPostProcessor。


    Set<String> processedBeans = new HashSet<String>();
 
    // 判断beanFactory是否为BeanDefinitionRegistry,beanFactory为DefaultListableBeanFactory,
    // 而DefaultListableBeanFactory实现了BeanDefinitionRegistry接口,因此这边为true
    if (beanFactory instanceof BeanDefinitionRegistry) {
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
        // 用于存放普通的BeanFactoryPostProcessor
        List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
        // 用于存放BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();
 
        // 首先处理入参中的beanFactoryPostProcessors
        // 遍历所有的beanFactoryPostProcessors, 将BeanDefinitionRegistryPostProcessor和普通BeanFactoryPostProcessor区分开
        for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
            if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                // 如果是BeanDefinitionRegistryPostProcessor
                BeanDefinitionRegistryPostProcessor registryProcessor =
                        (BeanDefinitionRegistryPostProcessor) postProcessor;
                // 直接执行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法
                registryProcessor.postProcessBeanDefinitionRegistry(registry);
                // 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
                registryProcessors.add(registryProcessor);
            } else {
                // 否则,只是普通的BeanFactoryPostProcessor
                // 添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)
                regularPostProcessors.add(postProcessor);
            }
        }

        2、根据优先级实现BeanDefinitionRegistryPostProcessor

        (1)找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName,存入postProcessorNames中(这里beanName是通过beanFactory.getBeanNamesForType从前一步obtainFreshBeanFactory方法中注册的beanName中找出的)

        (2)遍历postProcessorNames,过滤出实现了PriorityOrdered接口(排序用)的beanName。

        (3)使用beanFactory.getBean方法创建该BeanDefinitionRegistryPostProcessor对应的bean对象。将创建完成的bean对象存入currentRegistryProcessors,并将该beanName存入processedBeans。

        (4)根据PriorityOrdered接口的实现情况对currentRegistryProcessors排序,然后将currentRegistryProcessors存入registryProcessors中。

        (5)遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法。执行完毕后, 清空currentRegistryProcessors。

        (6)重复1-5步的过程,但会重新获取postProcessorNames,这是因为执行完上面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找。且这一步针对的是Ordered接口而不是PriorityOrdered接口。


        // 用于保存本次要执行的BeanDefinitionRegistryPostProcessor
        List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();

        // 调用所有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor实现类
        // 找出所有实现BeanDefinitionRegistryPostProcessor接口的Bean的beanName
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        // 遍历postProcessorNames
        for (String ppName : postProcessorNames) {
            // 校验是否实现了PriorityOrdered接口
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                // 获取ppName对应的bean实例, 添加到currentRegistryProcessors中,
                // beanFactory.getBean: 这边getBean方法会触发创建ppName对应的bean对象, 目前暂不深入解析
                currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                // 将要被执行的加入processedBeans,避免后续重复执行
                processedBeans.add(ppName);
            }
        }
        // 进行排序(根据是否实现PriorityOrdered、Ordered接口和order值来排序)
        sortPostProcessors(currentRegistryProcessors, beanFactory);
        // 添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
        registryProcessors.addAll(currentRegistryProcessors);
        // 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        // 执行完毕后, 清空currentRegistryProcessors
        currentRegistryProcessors.clear();
 

        // 调用所有实现了Ordered接口的BeanDefinitionRegistryPostProcessor实现类(过程跟上面的步骤3基本一样)
        // 找出所有实现BeanDefinitionRegistryPostProcessor接口的类, 这边重复查找是因为执行完上面的BeanDefinitionRegistryPostProcessor,
        // 可能会新增了其他的BeanDefinitionRegistryPostProcessor, 因此需要重新查找
        postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {
            // 校验是否实现了Ordered接口,并且还未执行过
            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);
        // 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
        invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
        currentRegistryProcessors.clear();

        3、实例化剩余BeanDefinitionRegistryPostProcessors与部分BeanFactoryPostProcessor

      (1)调用beanFactory.getBeanNamesForType找出所有实现BeanDefinitionRegistryPostProcessor接口的类,并跳过已经执行过的。

      (2)重复上一节中3、4、5步操作。

     (3)从registryProcessors中取出所有的BeanDefinitionRegistryPostProcessor,执行其postProcessBeanFactory方法。

     (4)调用入参beanFactoryPostProcessors中BeanFactoryPostProcessor的postProcessBeanFactory方法。


        // 最后, 调用所有剩下的BeanDefinitionRegistryPostProcessors
        boolean reiterate = true;
        while (reiterate) {
            reiterate = false;
            // 找出所有实现BeanDefinitionRegistryPostProcessor接口的类
            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);
                    // 如果有BeanDefinitionRegistryPostProcessor被执行, 则有可能会产生新的BeanDefinitionRegistryPostProcessor,
                    // 因此这边将reiterate赋值为true, 代表需要再循环查找一次
                    reiterate = true;
                }
            }
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
            // 遍历currentRegistryProcessors, 执行postProcessBeanDefinitionRegistry方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
        }
 

        // 6.调用所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(BeanDefinitionRegistryPostProcessor继承自BeanFactoryPostProcessor)
        invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
        // 最后, 调用入参beanFactoryPostProcessors中的普通BeanFactoryPostProcessor的postProcessBeanFactory方法
        invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    } else {
        
        invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    }

        4、针对BeanFactoryPostProcessor重复2、3步操作

          前三步之后,所有的BeanDefinitionRegistryPostProcessor都已处理完毕,包括入参beanFactoryPostProcessors和容器中注册的已经全部处理完毕,下面开始处理容器中的所有BeanFactoryPostProcessor。

         第4步则模仿前2步的操作,不过将BeanDefinitionRegistryPostProcessor替换为了BeanFactoryPostProcessor。


    // 找出所有实现BeanFactoryPostProcessor接口的类
    String[] postProcessorNames =
            beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
 
    // 用于存放实现了PriorityOrdered接口的BeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    // 用于存放实现了Ordered接口的BeanFactoryPostProcessor的beanName
    List<String> orderedPostProcessorNames = new ArrayList<String>();
    // 用于存放普通BeanFactoryPostProcessor的beanName
    List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    // 遍历postProcessorNames, 将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
    for (String ppName : postProcessorNames) {
        // 跳过已经执行过的
        if (processedBeans.contains(ppName)) {

        } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
            // 添加实现了PriorityOrdered接口的BeanFactoryPostProcessor
            priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
            // 添加实现了Ordered接口的BeanFactoryPostProcessor的beanName
            orderedPostProcessorNames.add(ppName);
        } else {
            // 添加剩下的普通BeanFactoryPostProcessor的beanName
            nonOrderedPostProcessorNames.add(ppName);
        }
    }
 
    // 调用所有实现PriorityOrdered接口的BeanFactoryPostProcessor
    // 对priorityOrderedPostProcessors排序
    sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    // 遍历priorityOrderedPostProcessors, 执行postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
 
    // 调用所有实现Ordered接口的BeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : orderedPostProcessorNames) {
        // 获取postProcessorName对应的bean实例, 添加到orderedPostProcessors, 准备执行
        orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    // 对orderedPostProcessors排序
    sortPostProcessors(orderedPostProcessors, beanFactory);
    // 遍历orderedPostProcessors, 执行postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
 
    // 调用所有剩下的BeanFactoryPostProcessor
    List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    for (String postProcessorName : nonOrderedPostProcessorNames) {
        // 获取postProcessorName对应的bean实例, 添加到nonOrderedPostProcessors, 准备执行
        nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    }
    // 遍历nonOrderedPostProcessors, 执行postProcessBeanFactory方法
    invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
 
    // 清除元数据缓存(mergedBeanDefinitions、allBeanNamesByType、singletonBeanNamesByType),
    // 因为后处理器可能已经修改了原始元数据,例如, 替换值中的占位符...
    beanFactory.clearMetadataCache();

总结:

        整个流程先从上下文中获取globalInitializerClasses、contextInitializerClasses参数配置的扩展点中手动添加到上下文中的BeanFactoryPostProcessor与BeanDefinitionRegistryPostProcessor。

        然后将他们分开存储,并实现BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法。再获取beanFactory中注册的BeanDefinitionRegistryPostProcessor,过滤出实现了PriorityOrdered接口的beanName,排序后依次实现。同样的步骤再针对Ordered接口重复执行。最后将beanFactory中剩余的BeanDefinitionRegistryPostProcessor类型的beanName依次执行postProcessBeanDefinitionRegistry方法。最后,调用入参beanFactoryPostProcessors中的BeanFactoryPostProcessor的postProcessBeanFactory方法。

        再然后,重复BeanDefinitionRegistryPostProcessor的处理过程,将对象替换为BeanFactoryPostProcessor。

举报

相关推荐

0 条评论