Spring初始化过程之invokeBeanFactoryPostProcessors

在spring的AbstractApplicationContext的refresh方法是启动spring容器的关键方法,我们本节用来介绍invokeBeanFactoryPostProcessors做了什么。

invokeBeanFactoryPostProcessors(beanFactory);

我们需要注意getBeanFactoryPostProcessors(),它是获取的手动注册的BeanFactoryPostProcessor。

    protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    }

什么叫手动,首先他不是作为Bean的形式存在于容器中的。我们可以看一个样例,这是在spring boot生命周期中的一个操作,处理ApplicationContextInitializer,里面的一个操作就是手动注册BeanFactoryPostProcessor。

    @Override
    public void initialize(ConfigurableApplicationContext context) {
        context.addBeanFactoryPostProcessor(
                new ConfigurationWarningsPostProcessor(getChecks()));
    }

下面开始我们的大头,这个invokeBeanFactoryPostProcessors中做的都是什么?

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) {

        // Invoke BeanDefinitionRegistryPostProcessors first, if any.
        Set processedBeans = new HashSet();

        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            List regularPostProcessors = new LinkedList();
            List registryPostProcessors =
                    new LinkedList();

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

            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the bean factory post-processors apply to them!
            // Separate between BeanDefinitionRegistryPostProcessors that implement
            // PriorityOrdered, Ordered, and the rest.
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

            // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            List priorityOrderedPostProcessors = new ArrayList();
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
            registryPostProcessors.addAll(priorityOrderedPostProcessors);
            invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

            // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            List orderedPostProcessors = new ArrayList();
            for (String ppName : postProcessorNames) {
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            sortPostProcessors(beanFactory, orderedPostProcessors);
            registryPostProcessors.addAll(orderedPostProcessors);
            invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

            // 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)) {
                        BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                        registryPostProcessors.add(pp);
                        processedBeans.add(ppName);
                        pp.postProcessBeanDefinitionRegistry(registry);
                        reiterate = true;
                    }
                }
            }

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

        else {
            // Invoke factory processors registered with the context instance.
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 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);

        // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
        // Ordered, and the rest.
        List priorityOrderedPostProcessors = new ArrayList();
        List orderedPostProcessorNames = new ArrayList();
        List 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.
        sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
        List orderedPostProcessors = new ArrayList();
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(beanFactory, orderedPostProcessors);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // Finally, invoke all other BeanFactoryPostProcessors.
        List nonOrderedPostProcessors = new ArrayList();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        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();
    }

看着挺长,其实里面的内容,比较简单。首先判断一下传入的beanFactory是不是BeanDefinitionRegistry的实例,这个BeanDefinitionRegistry是可以注册Bean的。然后处理我们手动注册的BeanFactoryPostProcessor,遍历每一个对象,验证是不是BeanDefinitionRegistryPostProcessor的实例。这里必须要插一点BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,这一点很重要的。我们接着聊,如果是BeanDefinitionRegistryPostProcessor的实例,那么就强制类型转换后,执行BeanDefinitionRegistryPostProcessor的生命周期方法postProcessBeanDefinitionRegistry,并且将这个BeanFactoryPostProcessor放入到registryPostProcessors容器中,如果不是BeanDefinitionRegistryPostProcessor的实例,那么直接放入到regularPostProcessors容器中。手动注册的放入容器中之后我们就可以处理容器中的属于BeanDefinitionRegistryPostProcessor类型的Bean了。

String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

processedBeans代表了一个已经处理过的Bean的容器,防止重复执行!
获取到的BeanDefinitionRegistryPostProcessor类型的Bean中,如果是PriorityOrdered类型的,那么会放入priorityOrderedPostProcessors容器中,然后排序,执行BeanDefinitionRegistryPostProcessor的生命周期方法postProcessBeanDefinitionRegistry。相同的方式再处理Ordered类型的,最后剩下的再单独处理。以上三种类型的postProcessBeanDefinitionRegistry处理完后,再执行BeanFactoryPostProcessor的生命周期方法postProcessBeanFactory。
这是一个条件分支,如果是beanFactory instanceof BeanDefinitionRegistry,如果不是的话,直接执行BeanFactoryPostProcessor的生命周期方法postProcessBeanFactory,将手动添加的BeanFactoryPostProcessor处理掉。
上面处理的是BeanDefinitionRegistryPostProcessor,下面我们再处理BeanFactoryPostProcessor

String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

处理的方式同BeanDefinitionRegistryPostProcessor一致,先处理完PriorityOrdered,再处理Ordered,最后处理普通的,这里要注意的是,因为BeanDefinitionRegistryPostProcessor也是BeanFactoryPostProcessor,并且他之前已经处理过了,所以这个过程就不会在处理了。

你可能感兴趣的:(Spring初始化过程之invokeBeanFactoryPostProcessors)