Spring容器初始化之BeanFactoryPostProcessor和BeanPostProcessor

        本文仍然以ClasspathXmlApplicationContext为入口进行记录,通过之前对Spring的学习,我们已知ClasspathXmlApplicationContext构造方法中调用的this.refresh()方法是整个Spring容器初始化的核心方法,refresh()方法调用过程如下:

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
            this.prepareRefresh();
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
//重要方法1                
this.invokeBeanFactoryPostProcessors(beanFactory);
//重要方法2
                this.registerBeanPostProcessors(beanFactory);
                beanPostProcess.end();
                this.initMessageSource();
                this.initApplicationEventMulticaster();
                this.onRefresh();
                this.registerListeners();
                this.finishBeanFactoryInitialization(beanFactory);
                this.finishRefresh();
            } catch (BeansException var10) {
                if (this.logger.isWarnEnabled()) {
                    this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var10);
                }

                this.destroyBeans();
                this.cancelRefresh(var10);
                throw var10;
            } finally {
                this.resetCommonCaches();
                contextRefresh.end();
            }

        }
    }

一、invokeBeanFactoryPostProcessors(beanFactory)

        进入refresh()方法,先来看这个方法调用:this.invokeBeanFactoryPostProcessors(beanFactory);这个方法的作用顾名思义,就是调用BeanFactory中存在的BeanFactoryPostProcessor,该方法实现了在Spring 启动期间,能够对BeanDefinition进行操作。在该方法内部又调用了这个方法:PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());核心操作都在这个方法里,具体实现如下:

public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        Set<String> processedBeans = new HashSet();
        ArrayList regularPostProcessors;
        ArrayList registryProcessors;
        int var9;
        ArrayList currentRegistryProcessors;
        String[] postProcessorNames;
        //判断BeanFactory是否是BeanDefinitionRegistry类型,如果是,走下面的逻辑
        //通过继承关系可以看出,BeanFactory就是BeanDefinitionRegistry类型
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
            regularPostProcessors = new ArrayList();
            registryProcessors = new ArrayList();
        //此处beanFactoryPostProcessors集合为空,因为此时还没有BeanFactoryPostProcessor加入到这个集合中。
            Iterator var6 = beanFactoryPostProcessors.iterator();
        //由于beanFactoryPostProcessors集合为空,因此这段while逻辑不会执行
            while(var6.hasNext()) {
                BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
                    registryProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryProcessors.add(registryProcessor);
                } else {
                    regularPostProcessors.add(postProcessor);
                }
            }

            currentRegistryProcessors = new ArrayList();
        //获取BeanFactory中类型是BeanDefinitionRegistryPostProcessor的类名
        //这里是能获取到有且只有一个,刚好是在前面<component-scan>标签解析最后,执行注册组件操作中加入到BeanDefinitionRegsitry中的ConfigurationClassPostProcessor
            postProcessorNames =         beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            String[] var16 = postProcessorNames;
            var9 = postProcessorNames.length;

            int var10;
            String ppName;
            for(var10 = 0; var10 < var9; ++var10) {
                ppName = var16[var10];
        //判断当前的BeanPostProcessor是否是PriorityOrdered类型
        //ConfigurationClassPostProcessor实现了PriorityOrdered接口,因此会进入这个if块
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        //进入if后,调用beanFactory.getBean()提前将ConfigurationClassPostProcessor实例化
        //将实例加入到了currentRegistryProcessors集合中
                            currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
        //对BeanFactoryPostProcessor进行排序
            sortPostProcessors(currentRegistryProcessors, beanFactory);
            registryProcessors.addAll(currentRegistryProcessors);
        //执行BeanDefinitionRegistryPostProcessor接口提供的postProcessBeanDefinitionRegistry()方法
            invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
            currentRegistryProcessors.clear();
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            var16 = postProcessorNames;
            var9 = postProcessorNames.length;

            for(var10 = 0; var10 < var9; ++var10) {
                ppName = var16[var10];
        //继续判断BeanPostProcessor是否实现了Ordered接口
        //ConfigurationClassPostProcessor没有实现Ordered接口,因此不会加入currentRegistryProcessors集合
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
        //processedBeans记录了已经处理过的类
                    processedBeans.add(ppName);
                }
            }
        //此时currentRegistryProcessors集合中为空
            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);
                String[] var19 = postProcessorNames;
                var10 = postProcessorNames.length;

                for(int var26 = 0; var26 < var10; ++var26) {
                    String ppName = var19[var26];
        //剩下的就是既没有实现PriorityOrdered接口,也没有实现Ordered接口的类
        //且不在processedBeans集合中,意味着在前面没有处理过,在这里处理
                    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();
            }
        //BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry()方法执行完了
        //接下来就是执行BeanFactoryPostProcessor中的postProcessBeanFactory()方法
        //由于BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor,因此这个类里也有这个方法
            invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
            invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        } else {
            invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        }

        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
        regularPostProcessors = new ArrayList();
        registryProcessors = new ArrayList();
        currentRegistryProcessors = new ArrayList();
        postProcessorNames = postProcessorNames;
        int var20 = postProcessorNames.length;

        String ppName;
        for(var9 = 0; var9 < var20; ++var9) {
            ppName = postProcessorNames[var9];
            if (!processedBeans.contains(ppName)) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
                } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    registryProcessors.add(ppName);
                } else {
                    currentRegistryProcessors.add(ppName);
                }
            }
        }

        sortPostProcessors(regularPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();
        Iterator var21 = registryProcessors.iterator();

        while(var21.hasNext()) {
            String postProcessorName = (String)var21.next();
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }

        sortPostProcessors(orderedPostProcessors, beanFactory);
        invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
        Iterator var24 = currentRegistryProcessors.iterator();

        while(var24.hasNext()) {
            ppName = (String)var24.next();
            nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
        }

        invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
        beanFactory.clearMetadataCache();
    }

        上面方法的核心就是实例化容器中的BeanFactoryPostProcessor,此时是BeanDefinitionRegistryPostProcessor,实际上就是之前在注册组件时加入进来的ConfigurationClassPostProcessor,这个类会在后面基于注解的Spring初始化流程中重点说明,它实现了BeanDefinitionRegistryPostProcessor接口,并依次调用接口需要实现的两个方法,分别为:postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)和postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)。

        这里需要着重记录的是,此处为Spring为我们提供的一个扩展点,即我们可以自己写一个类实现BeanDefinitionRegistryPostProcessor接口,并实现这两个方法,第一个方法传入了BeanDefinitionRegistry对象,我们知道这个对象为Spring的BeanDefinition注册器,能够对bd进行增删查改,这就使我们能够在程序启动过程中动态完成对某些bean的实例化或者修改操作。

        例如:我们实现如下一个类:

/**
* 这是我们自己实现的一个类,实现了BeanDefinitionRegistryPostProcessor接口
*/
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    //首先会调到这个方法里,并传入了registry对象,该对象中提供了对bd的各种操作
    //可以通过getBeanDefinition(String)方法获取某个待实例化类的bd对象,对里面的属性进行修改
        BeanDefinition bd = registry.getBeanDefinition("student");
        GenericBeanDefinition gbd = (GenericBeanDefinition) bd;
        MutablePropertyValues propertyValues = new MutablePropertyValues();
        propertyValues.addPropertyValue("username" , "tom");
        gbd.setPropertyValues(propertyValues);
    //也可以new出一个bd对象,将某个类变为bd对象,这样在spring进行实例化的时候,就会把该对象也加入到spring容器中
    //这样我们就又多了一种能够实例化springbean的方式,并且是在程序启动过程中动态生成的。
        GenericBeanDefinition gbd2 = new GenericBeanDefinition();
        gbd2.setBeanClass(Teacher.class);
        propertyValues = new MutablePropertyValues();
        propertyValues.addPropertyValue("name" , "Jerry");
        propertyValues.addPropertyValue("age" , 33);
        gbd2.setPropertyValues(propertyValues);
        registry.registerBeanDefinition("teacher" , gbd2);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    //然后会调用到这个方法中,这个方法中传入了configurableListableBeanFactory对象
    //其实这个类也是实现了BeanDefinitionRegistry接口。
    }
}

 二registerBeanPostProcessors(beanFactory)

         Spring容器初始化第二个重要的步骤,将BeanPostProcessor注册到BeanFactory中,BeanPostProcessor为我们提供了非常方便的扩展机制,在n个地方都为我们埋了扩展点,方便我们进行扩展。我们进入该方法,内部又进行了一步方法调用:PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);我们重点来看这个方法的实现过程:

public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
    //首先获取所有beanFactory中实现了BeanPostProcessor接口的类名
    //这里就是之前在注册组件时注册进来的两个分别为:
    //AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
    //new出这几个list是为了后面排序做准备
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList();
        List<String> orderedPostProcessorNames = new ArrayList();
        List<String> nonOrderedPostProcessorNames = new ArrayList();
        String[] var8 = postProcessorNames;
        int var9 = postProcessorNames.length;

        String ppName;
        BeanPostProcessor pp;
    //遍历所有实现上面接口的类名
        for(int var10 = 0; var10 < var9; ++var10) {
            ppName = var8[var10];
        //判断该类是否实现了PriorityOrdered接口
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
        //如果实现了PriorityOrdered接口,调用beanFactory.getBean()提前将该bean实例化,变为spring的bean
                pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
        //实现了PriorityOrdered接口的BeanPostProcessor实例都放到了priorityOrderedPostProcessors集合中
        //两个BeanPostProcessor都实现了该接口,因此都被加入priorityOrderedPostProcessors集合
                priorityOrderedPostProcessors.add(pp);
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
        //这两个BeanPostProcessor也都实现了MergedBeanDefinitionPostProcessor,因此也都被加入internalPostProcessors集合中
                    internalPostProcessors.add(pp);
                }
        //判断是否实现了Ordered接口,这里没有,因此这个集合是空的
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
        //这个集合也是空的
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        //对上面两个进行排序,排序后common在前面,autowired在后面
        sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
        //按顺序注册到beanFactory中,其实就是在beanFactory内部维护了一个beanPostProcessors的list,此时注册BeanPostProcessor的工作已经完成。
        registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
        Iterator var14 = orderedPostProcessorNames.iterator();
        //orderedPostProcessorNames这个集合是空的,因此不会走下面的循环
        while(var14.hasNext()) {
            String ppName = (String)var14.next();
            BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        sortPostProcessors(orderedPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
        Iterator var17 = nonOrderedPostProcessorNames.iterator();
        //这个集合也是空的,循环也不会走
        while(var17.hasNext()) {
            ppName = (String)var17.next();
            pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }

        registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
        sortPostProcessors(internalPostProcessors, beanFactory);
        registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

         该方法执行后就完成了BeanPostProcessor的注册工作,此时只有两个,即代码注释中提到的,另外,这里只是BeanPostProcessor的注册,还没有调用,在后面的过程中,会在各种不同的时机,对不同类型的BeanPostProcessor进行调用。

        还需要着重记录一下,这里便是Spring为我们提供的另一个扩展点,即自己写一个类实现BeanPostProcessor接口,BeanPostProcessor的子接口类型有很多,都是在不同的阶段调用的,在后面我们遇到的时候都会进行记录和总结,以便我们在今后的开发中能够灵活的对Spring进行扩展。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值