1. 程式人生 > >Spring原始碼解析—第五篇IOC之BeanFactoryPostProcessor

Spring原始碼解析—第五篇IOC之BeanFactoryPostProcessor

1、BeanFactoryPostProcessor簡介

和BeanPostProcessor原理一致,Spring提供了對BeanFactory進行操作的處理器BeanFactoryProcessor,簡單來說就是獲取容器BeanFactory,這樣就可以在真正初始化bean之前對bean做一些處理操作。

public class ChangeUserBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    //獲取beanFactory,在使用容器之前可以對一些bean做一些初始化操作
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }
}

2、例項

修改上面的例項,增加ChangeUserBeanFactoryPostProcessor

2.1、ChangeUserBeanFactoryPostProcessor類

public class ChangeUserBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    //獲取beanFactory,在使用容器之前可以對一些bean做一些初始化操作
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        User user = (User) beanFactory.getBean("user") ;
        user.setName("小王");
    }
}

2.2、配置檔案增加

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="user" class="com.vesus.spring.model.User" />
    <bean id="changeBeanUser" class="com.vesus.spring.processor.ChangeUserBeanFactoryPostProcessor" />
</beans>

2.3、測試類

public class Test {
    public static void main(String[] args) {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User) beanFactory.getBean("user") ;
        System.err.println(user.getName()+":"+user.getDesc());
    }
}

2.4、測試結果

我是小王!:使用者類

3、原始碼分析

3.1、入口方法refresh()

public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            .....
            try {
                ......
                //開始執行註冊到該上下文的BeanFactoryPostProcessors
                invokeBeanFactoryPostProcessors(beanFactory);
                .....
                //初始化單例
                finishBeanFactoryInitialization(beanFactory);
                .....
            }

            ....
        }
    }

從入口方法中可以看到,BeanFactoryPostProcessor 的註冊方法invokeBeanFactoryPostProcessors,下面分析invokeBeanFactoryPostProcessors 的註冊過程

3.2、invokeBeanFactoryPostProcessors註冊方法解析

public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        Set<String> processedBeans = new HashSet<>();

        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // 建立BeanFactoryPostProcessor型別的list,存放處理器
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<>();
            // 建立list,存放存放實現了BeanDefinitionRegistryPostProcessor的處理器
            List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList<>();
            // beanFactoryPostProcessors拿到的是空
            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                }
                else {
                    regularPostProcessors.add(postProcessor);
                }
            }

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

            //在beanFactory中獲取實現BeanDefinitionRegistryPostProcessor這個介面的bean的名稱
            String[] postProcessorNames =
                    beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            //註冊優先Order的處理器
            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();

            //註冊Order的處理器
            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();
            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();
            }

            //執行處理器中的方法
            invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }

        else {
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        //在beanFactory中獲取實現BeanFactoryPostProcessor這個介面的bean的名稱
        String[] postProcessorNames =
                beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

        //對實現了BeanFactoryPostProcessors的處理器按照PriorityOrdered、Ordered等進行排序
        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
            }
            //註冊實現了PriorityOrdered處理器
            else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
            }
            //註冊實現了Ordered處理器
            else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            }
            else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        //進行排序
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        //執行處理器中方法
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

        beanFactory.clearMetadataCache();
    }

至此,BeanFactoryPostProcessor的原始碼分析完成。