欢迎您的访问
专注架构,Java,数据结构算法,Python技术分享

深入理解Spring IOC(三) 、refresh方法中实例化前的准备工作

1.BeanDefinition的注册

在我们之前的文章中,我们已经把xml中的信息解析成了BeanDefiniton,然后我们需要注册他,其实所谓的注册也就是把解析出来的BeanDefiniton放到一个容器中去,以便在后边实例化的时候进行统一实例化。我们来看看下面的代码:

                                   代码块1
        @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
        // 1.我们前文所说过的XmlBeanDefinitionReader
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // 2.现在是在AbstractXmlApplicationContext,其父类既继承了DefaultResourceLoader的,也
        // 实现了ResourcePatternResolver
        beanDefinitionReader.setEnvironment(this.getEnvironment());
        beanDefinitionReader.setResourceLoader(this);
        beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // 3.设置验证模型
        initBeanDefinitionReader(beanDefinitionReader);
        // 4.加载Resource
        loadBeanDefinitions(beanDefinitionReader);
    }

这断代码相信大家已经很熟悉了吧,我们可以看到这个代码块的1处new了一个XmlBeanDefinitionReader,我们注意到,new的同时传了一个DefaultListableBeanFactory,这个DefaultListableBeanFactory它实现了了BeanDefinitionRegistry接口,换句话说,它也是一个BeanDefinitionRegistry的实例,这个东西起到了什么作用呢?我们来看看下面的中的第2处中代码调用方法的参数:

                                   代码块2
        protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
        if (bdHolder != null) {
            // 1.解析默认标签下的自定义标签
            bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
            try {
                // 2.注册beanDefiniton实例.
                BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
            }
            catch (BeanDefinitionStoreException ex) {
                getReaderContext().error("Failed to register bean definition with name '" +
                        bdHolder.getBeanName() + "'", ele, ex);
            }
            // Send registration event.
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
        }
    }

这也是之前文章中的代码了,第2处调用的方法的第二个参数这个getReaderContext().getRegistry()方法返回的,就是上面DefaultListableBeanFactory的实例,我们直接点进2处BeanDefinitionReaderUtils的registerBeanDefinition方法来看:

                                  代码块3
        public static void registerBeanDefinition(
            BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
            throws BeanDefinitionStoreException {

        // 1.注册beanDefinition
        String beanName = definitionHolder.getBeanName();
        registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

        // 2.注册别名
        String[] aliases = definitionHolder.getAliases();
        if (aliases != null) {
            for (String aliase : aliases) {
                registry.registerAlias(beanName, aliase);
            }
        }
    }

我们着重看1处,之前也说过,这个registry实际上就是个DefaultListableBeanFactory的实例,因此我们顺着这个类来找到DefaultListableBeanFactory里 的registerBeanDefinition方法:

                                      代码块4
        @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
            throws BeanDefinitionStoreException {
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");

        if (beanDefinition instanceof AbstractBeanDefinition) {
            try {
                // 1.校验,主要是校验method-override 和 factory-method(这两个不能共存)
                ((AbstractBeanDefinition) beanDefinition).validate();
            }catch (BeanDefinitionValidationException ex) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                        "Validation of bean definition failed", ex);
            }
        }

        BeanDefinition oldBeanDefinition;

        // 为什么要synchronized,因为其实ConcurrentHashMap并非绝对的线程安全
        synchronized (this.beanDefinitionMap) {
            oldBeanDefinition = this.beanDefinitionMap.get(beanName);
            if (oldBeanDefinition != null) {
                // 2.allowBeanDefinitionOverriding默认是true
                if (!this.allowBeanDefinitionOverriding) {
                    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
                            "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
                            "': There is already [" + oldBeanDefinition + "] bound.");
                // 3. bean的role 表示beanDefiniton的种类,是个int类型的变量,你可以理解成这个数字越大其代表的beanDefinition就越底层
                // 例如 1是用户定义的,2和3就都是配置相关的,只是配置级别不一样
                } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
                    if (this.logger.isWarnEnabled()) {
                        this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                                " with a framework-generated bean definition ': replacing [" +
                                oldBeanDefinition + "] with [" + beanDefinition + "]");
                    }
                } else {
                    if (this.logger.isInfoEnabled()) {
                        this.logger.info("Overriding bean definition for bean '" + beanName +
                                "': replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                    }
                }
            } else {
                // 把beanName放到专门用于存bean名称的集合用于后续创建对象用
                this.beanDefinitionNames.add(beanName);
                this.frozenBeanDefinitionNames = null;
            }
            // 4. 真真正正的注册,其实就是将这个beanDefinition放到一个map中
            this.beanDefinitionMap.put(beanName, beanDefinition);
        }

        if (oldBeanDefinition != null || containsSingleton(beanName)) {
            resetBeanDefinition(beanName);
        }
    }

我们可以看到,在4这个地方,将所有的解析好的BeanDefinition放到了一个Map容器中,到这里,完成了BeanDefinition的注册。

2.AbstractApplicationContext的refresh

可总算是到这里了,因为很多人看spring源码就是从这里开始的,也有很多人可能也就知道这个方法。总之今天会让你知道更多,我们直接到refresh方法这里:

                                     代码块5
        @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 1.加载前的准备工作
            prepareRefresh();
            // 2.获取一个全新的beanFactory实例
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            // 3.初始化beanFactory,给它设置各种
            prepareBeanFactory(beanFactory);
            try {
                // (空方法,让子类重写的)允许对beanFactory中的东西做一些前置的修改,可以是增加个BeanFactoryPostProcessors
                // 这种的,也可以给增加个BeanDefinition,也可以增加一些让beanFactory在自动装配时候忽略掉的接口,也可以增加一些特定场景使用的bean,
                // 比如有的后代就增加了新的scope bean 等等。但是重点是,我刚才说的这些都是基于一种具体场景的,因此这个抽象类里,
                // 这个方法是空的(不弄成抽象的原因是不强迫子类去实现)
                postProcessBeanFactory(beanFactory);

                // 4.触发调用所有的BeanFactoryPostProcessors(后边会讲这是个啥)
                invokeBeanFactoryPostProcessors(beanFactory);

                // 5.注册所有的BeanPostProcessor(后边会说)
                registerBeanPostProcessors(beanFactory);

                // 6.初始化支持国际化的东东
                initMessageSource();

                // 7. 初始化事件广播器
                initApplicationEventMulticaster();

                // 8. 初始化其他特殊的bean
                onRefresh();

                // 9. 注册监听器
                registerListeners();

                // 10. 实例化bean( 重点 )
                finishBeanFactoryInitialization(beanFactory);

                finishRefresh();
            } catch (BeansException ex) {
                logger.warn("Exception encountered during context initialization - cancelling refresh attempt", ex);
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
                // Reset 'active' flag.
                cancelRefresh(ex);
                // Propagate exception to caller.
                throw ex;
            }
        }
    }

尽管上面每一步都有注释,但是你肯定还是很懵逼,也不知道里面的方法到底都干了什么,为了容易一点让你理解,在这篇文章里,每一个大的部分都会被拆成很多小的部分讲,接下来我们针对上面代码块的每一个注释,展开说,每个细节都不放过。

在说之前有个需要大家注意的,我是基于之前那篇开始的代码debug,也就是说我们此时还是在用ClassPathXmlApplicationContext这个ApplicationContext的实现类,很多讲源码的文章都是直接说refresh方法,说真的,不基于使用场景去讲这个真的感觉像是在耍流氓。好了,吐槽的话说完了,我们开始

5.1

代码块5中1处调用的prepareRefresh主要是做的加载前的准备工作,我们直接来看prepareRefresh方法都做了什么

                                     代码块6
        protected void prepareRefresh() {
        // 1. 记录下容器开始刷新的时间
        this.startupDate = System.currentTimeMillis();
        // 2. 把容器标为激活状态
        synchronized (this.activeMonitor) {
            this.active = true;
        }

        if (logger.isInfoEnabled()) {
            logger.info("Refreshing " + this);
        }

        // 3. ClassPathXmlApplicationContext的时候调的是个空方法,跳过~
        initPropertySources();

        // 4. 调用StandardEnvironment中的validateRequiredProperties方法
        getEnvironment().validateRequiredProperties();
    }

上面的1、2、3处很容易理解,我们直接看4处的validateRequiredProperties方法,这块的这个代码其实是在AbstractEnvironment中:

                                   代码块7
        @Override
    public void validateRequiredProperties() throws MissingRequiredPropertiesException {
        this.propertyResolver.validateRequiredProperties();
    }

这里的这个propertyResolver是个PropertySourcesPropertyResolver的实例,这个玩意是用来解析存放一些环境变量以及配置用的(比如springboot的properties和yml的属性最后都会存放到这里面的propertySources中),我们直接来看PropertySourcesPropertyResolver的validateRequiredProperties方法,其实它是直接继承的AbstractPropertyResolver的这个方法:

                                  代码块8
        @Override
    public void validateRequiredProperties() {
        // 先new个异常
        MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
        // 如果需要的属性为空那么就把上一句new出来的异常抛出去
        for (String key : this.requiredProperties) {
            if (this.getProperty(key) == null) {
                ex.addMissingRequiredProperty(key);
            }
        }
        if (!ex.getMissingRequiredProperties().isEmpty()) {
            throw ex;
        }
    }

但是哈,debug的时候这个this.requiredProperties其实是空的,这是因为在创建StandardEnvironment的时候并没有去调用setRequiredProperties去添加必须属性,所以这个方法其实在我们讲的这个背景下p都没有干,但是我们还是需要注意PropertySourcesPropertyResolver(你最少要知道它是什么),因为这玩意在SpringBoot中是很重要的。

5.2

代码块5中2处这里主要的目的是获取一个全新的DefaultListableBeanFactory,并且,把xml中对应的信息加载成BeanDefinition放到这里面去。加载的过程我们之前文章就是专门讲的这个,这里不再赘述。

5.3

这里主要还是一些初始化工作

                                代码块9
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
        //设置类加载器:存在则直接设置/不存在则新建一个默认类加载器
        beanFactory.setBeanClassLoader(getClassLoader());
        //设置EL表达式解析器(Bean初始化完成后填充属性时会用到)
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
        //设置属性注册解析器PropertyEditor
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

        // Configure the bean factory with context callbacks.
        // 将当前的ApplicationContext对象交给ApplicationContextAwareProcessor类来处理,
        // 从而在Aware接口实现类中的注入applicationContext
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));

        //设置忽略自动装配的接口
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);

        // 注册可以解析的自动装配
        // BeanFactory interface not registered as resolvable type in a plain factory.
        // MessageSource registered (and found for autowiring) as a bean.
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);

        //如果当前BeanFactory包含loadTimeWeaver Bean,说明存在类加载期织入AspectJ,
        //则把当前BeanFactory交给类加载期BeanPostProcessor实现类LoadTimeWeaverAwareProcessor来处理,
        //从而实现类加载期织入AspectJ的目的。
        // Detect a LoadTimeWeaver and prepare for weaving, if found.
        if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            // Set a temporary ClassLoader for type matching.
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        //注册当前容器环境environment组件Bean
        // Register default environment beans.
        if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
        }
        //注册系统配置systemProperties组件Bean
        if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
        }
        //注册系统环境systemEnvironment组件Bean
        if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
            beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
        }
    }

虽然能给的注释我都给了,但是我估计你看到这个还是一脸懵逼,根本不知道这些东西是干什么用的,实在不明白,可以先混个脸熟,等后边看完了再返回到这里看。

5.4

这里是触发所有的BeanFactoryPostProcessor,关于BeanFactoryPostProcessor,接下来会有一篇扩展篇,专门说这个。我们在这里,可以先看这里的代码,因为这块其实很容易理解。

                                 代码块10
        protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
        PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
    }

我们可以看到,又是个delegate,那我们就直接去delegate里面去看:

                                 代码块11
        public static void invokeBeanFactoryPostProcessors(
            ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
        // 已经实例化过的processor的集合
        Set<String> processedBeans = new HashSet<String>();

        // 首先调用BeanDefinitionRegistryPostProcessors
        // 因为参数中的beanFactory是DefaultListableBeanFactory的实例,而DefaultListableBeanFactory实现了
        // BeanDefinitionRegistry,因此,if的条件是true
        if (beanFactory instanceof BeanDefinitionRegistry) {
            BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            // regularPostProcessors 是放普通的BeanFactoryPostProcessor的
            List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
            // 而这个registryPostProcessors是放BeanDefinitionRegistryPostProcessor的
            // 注意:BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor
            List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>();

            for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
                // 如果BeanFactoryPostProcessor是BeanDefinitionRegistryPostProcessor,
                if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
                    BeanDefinitionRegistryPostProcessor registryPostProcessor =
                            (BeanDefinitionRegistryPostProcessor) postProcessor;
                    // 执行BeanDefinitionRegistryPostProcessor,并加入registryPostProcessors集合
                    registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                    registryPostProcessors.add(registryPostProcessor);
                // 否则只加入regularPostProcessors集合
                } else {
                    regularPostProcessors.add(postProcessor);
                }
            }


            String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            // 首先调用实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessors
            List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
            for (String ppName : postProcessorNames) {
                if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                    // 注意,这里实例化了BeanDefinitionRegistryPostProcessor
                    priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            // 这个排序呢,其实是为了调整好那种既实现了PriorityOrdered,和Ordered的BeanDefinitionRegistryPostProcessor
            // 因为实现了PriorityOrdered也可以同时实现Ordered(虽然PriorityOrdered继承了Ordered,)在同时实现这两个接口的情况
            // 下,如果不排序,但是你的BeanDefinitionRegistryPostProcessor又需要这种执行顺序时候,在下面invoke的时候就会有问题
            // 接下来的排序也是这个道理
            OrderComparator.sort(priorityOrderedPostProcessors);
            // 把实现了 PriorityOrdered 的放到之前的 registryPostProcessors 中
            registryPostProcessors.addAll(priorityOrderedPostProcessors);
            // 执行实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor
            invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

            // 然后调用实现了 Ordered 的 BeanDefinitionRegistryPostProcessors
            // 为什么要重新拿这个数组呢?因为实现了 PriorityOrdered 的 BeanDefinitionRegistryPostProcessor 可以给你注册了实现
            // Ordered 和什么排序接口都没有的 BeanDefinitionRegistryPostProcessor
            postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
            for (String ppName : postProcessorNames) {
                // 执行过的跳过不执行
                if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
                    orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    processedBeans.add(ppName);
                }
            }
            OrderComparator.sort(orderedPostProcessors);
            registryPostProcessors.addAll(orderedPostProcessors);
            invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

            // 最后调用实现了其他的BeanDefinitionRegistryPostProcessors
            boolean reiterate = true;
            while (reiterate) {
                reiterate = false;
                postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
                // 外层之所以是个while循环,是因为BeanDefinitionRegistryPostProcessor可以再给你
                // 注册个BeanDefinitionRegistryPostProcessor进来,所以要循环执行,只要你的for循环可以进来
                // reiterate这个是否循环的flag就是true
                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;
                    }
                }
            }

            // 都是调用BeanFactoryPostProcessor的方法postProcessBeanFactory
            invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
            invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        }else {
            invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
        }

        // 这里有个很大的注意点哦:上面的逻辑都是在调用入参的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor
        // 而接下来的是调用beanFactory容器中的BeanFactoryPostProcessor,逻辑和上面类似,也是按实现PriorityOrdered,Ordered
        // 和普通的来调用。至于为什么要先调用BeanDefinitionRegistryPostProcessors然后调用BeanFactoryPostProcessor呢?这是因为
        // BeanDefinitionRegistryPostProcessors也可以注册新的BeanFactoryPostProcessor进来

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

        // 三个优先级的BeanFactoryPostProcessor的集合
        List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        for (String ppName : postProcessorNames) {
            // 如果已经被解析过则跳过
            if (processedBeans.contains(ppName)) {

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

        // 排序并调用高优先级的BeanFactoryPostProcessor
        OrderComparator.sort(priorityOrderedPostProcessors);
        invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

        // 初始化一般优先级BeanFactoryPostProcessor并排序调用
        List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
        for (String postProcessorName : orderedPostProcessorNames) {
            orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        OrderComparator.sort(orderedPostProcessors);
        invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

        // 初始化普通的BeanFactoryPostProcessor并排序调用
        List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
        for (String postProcessorName : nonOrderedPostProcessorNames) {
            nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
        }
        invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    }

代码比较长,但是思路还是很清晰的,总体也就是先按顺序调用BeanDefinitionRegistryPostProcessor,然后按同样的顺序调用BeanFactoryPostProcessor。

5.5

这里是注册所有的BeanPostProcessor的,注意哈,不会调用的,因为这个BeanPostProcessor必须等到Bean初始化之后才可以被调用。我会在和BeanFactoryPostProcessor同一篇文章中去说这个BeanPostProcessor。我们同样的可以直接来看注册BeanPostProcessor的源码(因为简单),还是在和上面代码块相同的一个类中,只不过是另外一个方法:

                                 代码块12
        public static void registerBeanPostProcessors(
            ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        // 拿到所有的BeanPostProcessor名称
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

        // 优先注册一个BeanPostProcessorChecker的实例,这玩意是用作在BeanPostProcessor初始化的这个过程
        // 做检查用的,检查内容见扩展篇
        int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
        beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

        // 还是熟悉的套路,将三种优先级别的BeanPostProcessor分开
        List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
        List<String> orderedPostProcessorNames = new ArrayList<String>();
        List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        for (String ppName : postProcessorNames) {
            // 先实例化实现了PriorityOrdered的,并加入集合
            if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
                priorityOrderedPostProcessors.add(pp);
                // 如果是MergedBeanDefinitionPostProcessor,则加入internalPostProcessors
                if (pp instanceof MergedBeanDefinitionPostProcessor) {
                    internalPostProcessors.add(pp);
                }
            } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
                orderedPostProcessorNames.add(ppName);
            } else {
                nonOrderedPostProcessorNames.add(ppName);
            }
        }

        // 排序并注册
        OrderComparator.sort(priorityOrderedPostProcessors);
        registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

        // 接着注册实现了Ordered的
        List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : orderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            orderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        OrderComparator.sort(orderedPostProcessors);
        registerBeanPostProcessors(beanFactory, orderedPostProcessors);

        // 再注册普通的
        List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
        for (String ppName : nonOrderedPostProcessorNames) {
            BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
            nonOrderedPostProcessors.add(pp);
            if (pp instanceof MergedBeanDefinitionPostProcessor) {
                internalPostProcessors.add(pp);
            }
        }
        registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

        // 重新注册所有的实现了MergedBeanDefinitionPostProcessor的(为了移动到处理链路的最后一个)
        // 不明白什么是处理链路的先往下看,到后边自然会明白
        OrderComparator.sort(internalPostProcessors);
        registerBeanPostProcessors(beanFactory, internalPostProcessors);

        // 重新注册ApplicationListenerDetector(也是为了移动到处理链路的最后一个)
        beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
    }

实际上和之前注册BeanFactoryPostProcessor的方式类似,这里不做过多的解释,看注释即可。

代码块5的6、7、8、9这四处代码不属于核心流程,我们暂时不关注这些。至此,实例化bean的前期准备工作已经做完。我们总结一下,使用xml的这种情况下,在refresh方法中bean实例化之前,主要干了这么几件事,首先需要把所有的BeanDefinition加载进BeanFactory容器这个是在refresh的第二步做的,接下来是需要在prepareBeanFactory中率先初始化一些基本的bean,然后是调用所有的BeanFactoryPostProcessor去对BeanDefinition做后置处理,接着去注册所有的BeanPostProcessor,再下来是国际化、事件广播器以及监听器的初始化。在这其中,最重要的,是加载BeanDefinition这步以及调用BeanFactoryPostProcessor的这步,因为这两步中,我们都是可以插手去做扩展的。

赞(1) 打赏
版权归原创作者所有,任何形式转载请联系作者;码农code之路 » 深入理解Spring IOC(三) 、refresh方法中实例化前的准备工作

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏