spring步步前行(IOC)-Spring beanFactory详解(二)

前言

​ 承接上一篇,上一篇我们分析了spring beanFactory如何初始化自身,以及如何如何加载我们xml中配置的bean,在此处我们简单的总结下:

  • 1.内部替我们创建了一个DefaultListableBeanFactory,设置序列化id,并提供一些可定制化的设
  • 2.通过XmlBeanDefinitionReader找到我们的xml并解析,将我们配置的bean加载注册到我们的facotry容器中

导语

上一篇我们分析了obtainFreshBeanFactory的方法,我们接着看refresh其他操作方法

在这里插入图片描述

首先我们从refresh整体方法上看,refresh都有什么样子的操作:

  • 允许上下文子类在beanfactory初始化之后修改其内部的beanfactory
  • 注册所有BeanPostProcessor
  • 初始化事件处理集
  • 注册拦截bean创建的所有bean处理器
  • 初始化消息源也就是国际化支持的bean
  • 注册将ApplicationListener实现为侦听器的bean
  • 实例化所有设置单例的bean

等这些操作,接下来,我们从这些方法上一一分析,来了解bean是如何初始化的

refresh的postProcessBeanFactory

首先我们能看到第一个方法postProcessBeanFactory,我们看其实现,看到AbstractApplicatonContext中为空实现,均是由其子类实现,对于AbstractApplicationContext相当于留给子类一个hook方法,这个方法我们延迟放在以后的demo文章尾篇介绍该功能

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

从此处我们可以看到大致操作,可分为两部分

  • 即首先通过getBeanFactoryPostProcessor获取所有已注册的beanFactoryPostProcessor
  • 对获取到的beanFactoryPostProcessor实例化并调用所有

由于PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors的方法过长这里就不贴,我们分析一点贴一点

首先我们一进来就进入了一个if条件判断的方法块中,条件是对BeanDefinitionRegistry的类型进行处理,对于BeanDefinitionRegistry类型的解析,从之前的篇章我们知道,我们的beanfactory为DefaultListableBeanFactory,而DefaultListableBeanFactory自身我们可看到它已实现了BeanDefinitionRegistry接口。


在这里插入图片描述

先new了两个容器,一个盛放的是BeanFactoryPostProcessor,另一个盛放的是BeanDefinitionRegistryPostProssessor。

  • 第一步:还是通过遍历所有已注册的BeanFactoryPostProcessor,若为BeanDefinitionRegistryPostProcessor,先调用自身的postProcessBeanDefinitionRegitstry,让后加入到盛放BeanDefinitionRegistryPostProcessor的容器内,若不是BeanDefinitionRegistryPostProcessor,则直接加入到盛放BeanFactoryPostProcessor的容器内

  • 第二步:从我们的beanfactory的getBeansOfType找出所有实现了BeanDefinitionRegistryPostProcessor,通过OrderCcomparator对这些Processor进行排序,然后遍历执行postProcessBeanDefinitionRegistry

  • 第三步:invokeBeanFactoryPostProcessors具体方法如下:


    在这里插入图片描述

即遍历执行每个postProcessor的postProcessBeanFactory方法进行注册

到这里 , 我们看到的均是对BeanDefinitionRegistryPostProcessor的处理,这里也就是对BeanDefinitonRegistryPostProcessor的处理已经全部完毕, 下面是对BeanFactoryPostProcessor的处理

接下来方法是如下:


在这里插入图片描述
  • 第一步:通过beanFactory的getBeanNamesForType方式查找所有的实现BeanFactoryPostProcessor的类
  • 第二步:声明三个容器,一个盛放实现PriorityOrdered接口的容器,一个盛放实现Ordered接口的beanName的容器,还有一个盛放普通postProcessor的beanName的容器
  • 第三步:对查找出来的所有BeanFactoryPostProcessor的类进行遍历,分类存放对应的类。而priorityOrderedPostProcessor内存放的BeanFactoryPostProcesor则通过beanfactory的getBean方式获取到
  • 第四步:借助OrderComparator对priorityOrderedPostProcessors进行排序,并遍历执行postProcessBeanFactory向beanfactory进行注册
  • 第五步:创建一个orderedPostProcessors容器,遍历orderedPostProcessorNames,向创建的orderedPostProcessors存放通过beanfactory的getBean方式获取到PostProcessor

getBean追踪

从上面的getBean处我们了解需要从beanFactory处获取实例bean我们深入看看,最终我们定位到AbstractFactory的doGetBean


在这里插入图片描述
  • 首先先去实例化好的bean中去找,如果找到,直接返回

  • 去当前beanfactory中父类factory找,如果能找到父类的factory,则叫父类去返回(有点像classloader的双亲模型呀)

  • 开始查看当前要实例化的bean是否依赖于其他的bean,如果依赖,则先实例化依赖的bean,如果依赖的bean还依赖于其他的bean,则接着递归创建


    在这里插入图片描述
  • 如果创建的bean是单例(spring默认单例)接着创建


    在这里插入图片描述
  • 我们跟着createBean看起处理到AbstractAutowireCapableBeanFactory


    在这里插入图片描述

    到这里getbean就为我们准备好了目标的bean

到这里对OrderedPostProcessor的处理,就结束了,紧跟着是对普通PostProcessor的处理,由于一致,这里就不一一分析,将处理代码如下展示:


在这里插入图片描述

可能有人好奇OrderComparator的排序是什么样子的,这里我做简单分析:

public int compare(Object o1, Object o2) {
        boolean p1 = o1 instanceof PriorityOrdered;
        boolean p2 = o2 instanceof PriorityOrdered;
        if(p1 && !p2) {
            return -1;
        } else if(p2 && !p1) {
            return 1;
        } else {
            int i1 = this.getOrder(o1);
            int i2 = this.getOrder(o2);
            return i1 < i2?-1:(i1 > i2?1:0);
        }
    }

public static void sort(List list) {
        if(list.size() > 1) {
            Collections.sort(list, INSTANCE);
        }

    }
其实就是借助Collections进行排序,通过比较getOrder实现排序

至此invokeBeanFactoryPostProcessors部分就分析完毕了,此处我们简单做个总结:

整个invokeBeanFactoryPostProcessros围绕着BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor这两个接口,从上面分析可知,BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor均是注册bean用的,但是BeanDefinitionRegistryPostProcessor执行优先于BeanFactoryPostProcessor
操作3种bean对象向beanfactory中注册
1.beanfactory中之前添加的beanFactoryPostProcessor
2.实现了BeanDefinitionRegistryPostProcessor接口的postProcessor
3.实现了BeanFactoryPostProcessor接口的postProcessor
将这三种bean向beanFactory中注册

refresh的registerBeanPostProcessors

registerBeanPostProcessors和invokeBeanFactoryPostProcessros很相像,
首先先看它的具体方法:


在这里插入图片描述
  • 也是通过beanFactory的getBeanNamesForType找到所有实现BeanPostProcessor的所有类

  • 添加ProcessorChecker这个PostProcessor进beanFactory
    在这里插入图片描述

    很容易,我们发现这个PostProcessor并没有什么特殊操作,只是进行logger.info操作,用来记录一些信息

  • 紧跟着声明了四个容器,和invokeBeanFactoryPostProcessros声明的那三个一致,但是多了一个internalPostProcessors,即用来盛放实现了MergedBeanDefinitionPostProcessor接口的容器(即需要重新注册所有内部BeanPostProcessors)

  • 对priorityOrderedPostProcessor进行分类对于实现了MergedBeanDefinitionPostProcessor就向internalPostProcessor添加一份

  • 紧跟着借助OrderComparator排序,然后遍历priorityOrderedPostProcessors进行注册beanPostProcessor


    在这里插入图片描述

    即通过beanfactory的addBeanPostPrcossor想beanfactory进行注册beanPostprocessor

对于orderedPostProcessorNames和nonOrderedPostProcessorNames处理方式和priorityOrderedPostProcessors一致,唯一不同的跟invokeBeanFactoryPostProcessors一样,通过beanFactory的getBean对name进行替换


在这里插入图片描述

对于internalPostProcessors的操作,即重新注册所有内部BeanPostProcessors:

OrderComparator.sort(internalPostProcessors);
this.registerBeanPostProcessors(beanFactory, internalPostProcessors);

1.排序
2.注册beanPostProcessor
3.通过beanFactory的addBeanPostProcessor添加BeanPostProcessor

最后通过beanFactory的addBeanPostProcessor添加了一个ApplicationListenerDetector的BeanPostProcessor


在这里插入图片描述

可以看到其也是实现了MergedBeanDefinitionPostProcessor,其主要功能是用来检测bean是否是ApplicationListener,如果是判断是否是单例,如果不是单例,那么删除singtonNames中对应的key

由此整个方法也就到这结束了

小小的总结下:

registerBeanPostProcessors与invokeBeanFactoryPostProcessors一致,一个是对BeanPostProcessor的处理,一个是对BeanFactoryPostProcessor的处理,对于BeanPostProcessor而言,对内部的beanPostProcessor重新注册一次

至此对于beanPostProcessor和BeanFactoryPostProcessor,我们就分析到这,我们可以看到spring为我们bean创建等提供了很多由我们自由控制的时机,未避免篇幅太长,后续方法我们下篇继续

你可能感兴趣的:(spring步步前行(IOC)-Spring beanFactory详解(二))