美文网首页
Spring源码-invokeBeanFactoryPostPr

Spring源码-invokeBeanFactoryPostPr

作者: Wannay | 来源:发表于2021-05-03 21:46 被阅读0次

    1.invokeBeanFactoryPostProcessors方法的源码

    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 (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
                beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
                beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
            }
        }
    

    但是其真实的逻辑其实在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中。

    2.关于BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor和ConfigurationClassPostProcessor之间的关系

    在这个方法中会涉及到几个概念,叫BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor和ConfigurationClassPostProcessor。

    2.1我们来看BeanDefinitionRegistryPostProcessor的继承关系

    在PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中会涉及到几个概念,叫BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor和ConfigurationClassPostProcessor。

    我们来看BeanDefinitionRegistryPostProcessor的继承关系

    public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
    

    我们可以看到BeanDefinitionRegistryPostProcessor其实是BeanFactoryPostProcessor的子接口。

    2.2 我们再来看一个类ConfigurationClassPostProcessor的继承关系

    public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
            PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware
    

    我们可以看到ConfigurationClassPostProcessor实现了PriorityOrdered接口和BeanDefinitionRegistryPostProcessor接口。

    3.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors

    第一行代码是一个HashSet,名叫processedBeans,顾名思义,就是用来保存已经处理过的Bean(BeanFactoryPostProcessor)的Name。在后面的代码中可以用来避免PostProcessor的Bean被重复调用,每次添加到对应的列表中,都会先判断是否已经在这个Set中。

    Set<String> processedBeans = new HashSet<>();
    

    接着是这样的代码,想要拿到BeanDefinitionRegistryPostProcessor的实现类。

    //判断beanFactory是否是BeanDefinitionRegistry的实例
    if (beanFactory instanceof BeanDefinitionRegistry) {  
        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; 
    

    如果BeanFactory是BeanDefinitionRegistry的实例,就将BeanFactory转换成BeanDefinitionRegistry。

    接着,是两个List,regularPostProcessors用来保存普通的BeanFactoryPostProcessor的实现类(Bean),registryProcessors则是保存BeanDefinitionRegistryPostProcessor的实现类(Bean)。

    List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    

    看接下来的代码,这段代码主要用来判断它是不是BeanDefinitionRegistryPostProcessor,如果是,就调用postProcessBeanDefinitionRegistry方法(这个方法就是子接口BeanDefinitionRegistryPostProcessor实现的,并不是BeanFactory接口提供的),并把它放在registryProcessors列表中;如果不是,就把它放在regularPostProcessors列表中。遍历beanFactoryPostProcessors的列表,但是这里一般好像beanFactoryPostProcessors里都没东西,不用遍历。

    那么Spring为什么要加这个逻辑呢?其实这是Spring作为一个框架留给我们的扩展点,我们可以手动往beanFactoryPostProcessors这个集合中添加一些BeanFactoryPostProcessor,让这些BeanFactoryPostProcessor在Spring内置的BeanFactoryPostProcessor执行之前就被执行。比如下面这段代码就会在Spring执行内置的BeanDefinitionRegistryPostProcessor之前先去执行我们自定义的BeanDefinitionRegistryPostProcessor的逻辑。

                for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                    if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                        BeanDefinitionRegistryPostProcessor registryProcessor =
                                (BeanDefinitionRegistryPostProcessor) postProcessor;
                        registryProcessor.postProcessBeanDefinitionRegistry(registry);
                        registryProcessors.add(registryProcessor);
                    } else {
                        regularPostProcessors.add(postProcessor);
                    }
                }
    

    那么我们如何往这里添加BeanDefinitionRegistryPostProcessor,让它在这里就执行呢?我们可以使用如下的方式去手动添加。

            //这里要使用AnnotationConfigApplicationContext去创建,不能使用ApplicationContext接口去创建
            //因为addBeanFactoryPostProcessor方法是在AnnotationConfigApplicationContext中实现的
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            context.register(App.class);  //手动注册
            context.addBeanFactoryPostProcessor(new MyBeanDefinitionRegistryPostProcessor());
            context.refresh();
    

    这段代码是不是很熟悉?

        public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
            this();
            register(componentClasses);
            refresh();
        }
    

    其实这就和我们传入一个componentClasses参数的方式很类似,我们只不过在refresh方法执行之前往容器中加入了我们自定义的BeanFactoryPostProcessor。


    image.png

    我们可以看到,我们自己加进去的PostProcessor在这里就已经能拿到了。这样,我们就成功添加了我们自己的PostProcessor,在Spring执行内置的PostProcessor之前,就会先执行我们自己先加进去的方式。

    接下来是一个列表currentRegistryProcessors,这个列表中来存放当前正在执行的BeanDefinitionRegistryPostProcessor。

    List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    

    接着是这样一段代码,这段代码主要是拿到BeanDefinitionNames作为Key,再通过BeanDefinitionMap拿到BeanDefinition的Class是否实现了BeanDefinitionRegistryPostProcessor接口,如果实现了那么就将Key加入到postProcessorNames中,再根据BeanDefinitionName去BeanFactory中拿BeanDefinition,看它是否实现了PriorityOrdered接口。在invokeBeanDefinitionRegistryPostProcessors方法中则将这些PostProcessor进行实例化,调用getBean-doGetBean-createBean-doCreateBean一系列的方法去创建PostProcessor的Bean并进行执行。

                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);
                //这里会执行Spring内置的PostProcessor--->
                //ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry
                //执行这里之后就会将我们自己实现的BeanRegistryPostProcessor扫描进来
                invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
                //清除列表,避免重复执行
                currentRegistryProcessors.clear();
    

    需要注意的是使用如下的方式去拿到BeanFactory,由于构造方法中就执行了scan(basePackages)这个方法,将BeanDefinition已经加载到BeanDefinitionMap中。

    ApplicationContext context = new AnnotationConfigApplicationContext("com.wanna.bean");
    

    如果是使用的如下方式去拿到BeanFactory,则是在refresh方法的第二步执行的obtainFreshBeanFactory方法中将BeanDefinition加载到BeanFactory中的。

    ApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    

    如果是使用的是如下方式去拿到BeanFactory,则是在 invokeBeanDefinitionRegistryPostProcessors这个方法中的postProcessor.postProcessBeanDefinitionRegistry(registry)这个步骤才将非Spring内置的BeanDefinition加载到BeanFactory中。使用这种方式在调用之前,BeanFactory中只有ConfigurationClassPostProcessor这一个BeanDefinition的Class是实现了PriorityOrdered接口的。在执行invokeBeanDefinitionRegistryPostProcessors时,调用的ConfigurationClassPostProcessor这个类的postProcessBeanDefinitionRegistry方法将用户自定义的BeanDefinition扫描进来。但是如果是使用另外的两种方式,这里调用之前就已经可以拿到我们自定义的BeanDefinitionRegistryPostProcessor的BeanDefinition了

    ApplicationContext context = new AnnotationConfigApplicationContext(App.class)
    

    也就是到这里,无论哪种方式都已经将BeanDefinition加载到BeanFactory中,后面要用到只需要拿来进行创建Bean即可。

    在invokeBeanDefinitionRegistryPostProcessors方法中还会将实现了PriorityOrdered接口的Bean给创建出来并执行postProcessBeanDefinitionRegistry。也就是如果我们自定义如下的BeanDefinitionRegistryPostProcessor,也会在这里执行postProcessBeanDefinitionRegistry方法,打印Wanna--postProcessBeanDefinitionRegistry这句话。

    @Component
    public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            System.out.println("Wanna-postProcessBeanFactory");
        }
    
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
            System.out.println("Wanna--postProcessBeanDefinitionRegistry");
        }
    
        @Override
        public int getOrder() {
            return 0;
        }
    }
    

    接下来这段代码和上面的类似,只不过这里是调用的是实现了BeanDefinitionRegistryPostProcessor和Ordered接口的实现类(Bean)。在invokeBeanDefinitionRegistryPostProcessors方法中则将这些PostProcessor进行实例化,调用getBean-doGetBean-createBean-doCreateBean一系列的方法去创建PostProcessor的Bean并进行执行。

                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, beanFactory.getApplicationStartup());
                currentRegistryProcessors.clear();
    

    下面段代码也是很类似,调用的是实现了BeanDefinitionRegistryPostProcessor接口,但是没实现Ordered接口和PriorityOrdered接口的实现类(Bean)。在invokeBeanDefinitionRegistryPostProcessors方法中则将这些PostProcessor进行实例化,调用getBean-doGetBean-createBean-doCreateBean一系列的方法去创建PostProcessor的Bean并进行执行。

                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, beanFactory.getApplicationStartup());
                    currentRegistryProcessors.clear();
                }
    

    接着,下一段,这里第一个方法会调用BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法(需要说明的是,BeanDefinitionRegistryPostProcessor这个接口有两个方法,一个来自于BeanFactoryPostProcessor,另一个来自于BeanDefinitionRegistryPostProcessor自己实现的,上面调用的都只是postProcessBeanDefinitionRegistry方法,而这里调用的是postProcessBeanFactory方法),也就是Wanna-postProcessBeanFactory这句话会在第一个方法执行完之后打印,regularPostProcessors一般为null。在上面我们讲了会在执行Spring内置的BeanDefinitionRegistryPostProcessor之前可以执行我们自己使用API方式定义的BeanDefinitionRegistryPostProcessor。而这里调用的第二个方法其实就是保证我们使用API方式往容器中加入的普通BeanFactoryPostProcessor能够先执行,再执行其他的BeanFactory。

                // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
                invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
                invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    

    下面一大段代码也是类似,只不过这里执行的是并没有实现BeanDefinitionRegistryPostProcessor,仅仅实现了普通BeanFactoryPostProcessor接口的实现类。也是依次执行实现了PriorityOrdered接口、Ordered接口、既没有实现PriorityOrdered又没有实现Ordered接口的实现类。利用BeanDefinition进行实例化,并调用postProcessBeanFactory方法。

            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
            // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
            // Ordered, and the rest.
            // 2.将实现了PriorityOrdered、Ordered接口的BeanFactoryPostProcessor和剩下的分开并进行调用
            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);
                }
            }
    
            // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
            // 2.1将实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序并进行调用
            sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
            // 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));
            }
            // 2.2将实现了Ordered接口的BeanFactoryPostProcessor进行排序并调用
            sortPostProcessors(orderedPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
            // Finally, invoke all other BeanFactoryPostProcessors.
            List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
            for (String postProcessorName : nonOrderedPostProcessorNames) {
                nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
            }
            // 2.3调用既没有实现PriorityOrdered接口、也没有实现Ordered的BeanFactoryPostProcessor
            invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
            // Clear cached merged bean definitions since the post-processors might have
            // modified the original metadata, e.g. replacing placeholders in values...
            beanFactory.clearMetadataCache();
    

    相关文章

      网友评论

          本文标题:Spring源码-invokeBeanFactoryPostPr

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