spring 的后置处理器

973 阅读4分钟

spring的后置处理器

spring提供了三种后置处理器

  1. BeanFactoryPostProcessor
  2. BeanPostProcessor
  3. InitializingBean 我们来依次看每个后置处理器的执行流程。

BeanFactoryPostProcessor

首先还是回到refresh方法中,我们可以看到在创建普通bean对象的上面有个方法叫invokeBeanFactoryPostProcessor,从方法名就可以看出是执行BeanFactoryPostProcessor方法 image.png 方法内部调用了一个代理类的静态方法 image.png 方法内部会首先拿出实现了PriorityOrdered接口的对象排序后执行 image.png

image.png 执行完PriorityOrdered接口后再拿出实现了Order接口的对象执行 image.png 最后把剩下的BeanFactoryPostProcessor根据类名排序后调用方法,这时候容器里面还是没有对象的,在getBean的时候需要走原来看过的创建普通bean的流程 image.png 前面的都是执行的BeanDefinitionRegistryPostProcessor的方法postProcessBeanDefinitionRegistry,三个判断结束之后最后执行BeanFactoryPostProcessorpostProcessBeanFactory方法 流程图如下

image.png

工厂后置增强的实际用途

我们现在知道了spring提供了一些工厂的后置处理器来增强工厂,那么我们现在来看看spring中实际使用工厂后置处理器做了什么事情,我们来看一个类ConfigurationClassPostProcessor image.png 这个类是用于处理写了@Configuratioin注解的类 image.png 排序好之后就在一个循环里面解析容器里面的类 image.png 在方法中先判断是不是需要跳过,如果写了@Conditional注解的对象会判断条件是否生效 image.png 真正解析配置类的方法里面就是各种判断注解的情况,然后去做相应的方法 image.png

BeanPostProcessor 注册

工厂的增强至此就结束了,接下来看看普通组件的后置处理器的逻辑,还是回到refresh方法,这次是调用registerBeanPostProcessors方法,注册后置处理器。 image.png 注册的逻辑跟BeanFactory都是由同一个代理类来完成的 image.png 大部分逻辑和bean工厂的逻辑一致,都是判断优先级接口的就先执行 image.png 跟bean工厂不一致的是,bean工厂的后置处理器直接执行目标方法,这里只是把bean后置处理器创建好之后就放入list中 image.png

InstantiationAwareBeanPostProcessor

所有的BeanPostProcessor都被注册之后,我们来看其中一个分支:InstantiationAwareBeanPostProcessor 的流程

SmartInstantiationAwareBeanPostProcessor

image.png 从名字上可以看出叫智能的实例后置处理器,那么这个我们就来看看智能在什么地方. 在refresh方法中调用了一个注册监听器的方法 image.png 在该方法中调用了一个根据类型获取名称列表的方法,该方法是ListableBeanFactory接口的一个方法 image.png 为了获得目标类的名称,spring遍历所有的bean的名称,一个一个判断

image.png 判断逻辑是先判断已经初始化好的实例,然后再判断bean定义信息,如果都没有则让别人来判断 image.png 拿到容器中的SmartInstantiationAwareBeanPostProcessor然后把类名和bean名称穿进去,让实现类来决定 image.png 总结流程图 image.png 所以我们知道,在spring中,根据类型来找名称其实spring需要遍历所有对象,是一件很麻烦的事情

InstantiationAwareBeanPostProcessor

image.png 在spring容器创建对象之前,会先调用 InstantiationAwareBeanPostProcessor的 postProcessBeforeInstantiation方法尝试返回对象,如果用户返回了则会用用户创建的对象。 image.png 如果没有则调用doCreateBean方法,方法内也会从一个缓存中获取,没有的话就继续调用方法创建 image.png 创建逻辑会让用户返回一个构造函数,注意这里调用的是SmartInstantiationAwareBeanPostProcessor的一个方法,如果没有就用默认的无参构造函数,之后就是上面写过的用工具类创建的方式 image.png

MergedBeanDefinitionPostProcessor

在创建好bean实例对象之后会调用一下MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法让用户定义一下BeanDefinition image.png

PopulateBean

之后就进入属性赋值方法,首先会先执行 InstantiationAwareBeanPostProcessorpostProcessAfterInstantiation方法,返回bool类型的值,如果返回true则会继续属性赋值,返回false则不会属性赋值 image.png 如果返回true则开始执行InstantiationAwareBeanPostProcessorpostProcessProperties方法。自动注入 AutowiredAnnotationBeanPostProcessor的该方法就实现了自动注入的属性赋值 image.png

PropertyValues

在上面我们可以看到postProcessProperties方法返回了一个pvs,我们也可以自定义返回pvs,spring最后会帮我们注入到对象中,创建一个PVS返回即可 image.png

BeanPostProcessor

属性赋值之后spring会执行initializeBean 方法初始化bean,首先会先执行一些 Aware的注入

  1. BeanNameAware
  2. BeanClassLoaderAware
  3. BeanFactoryAware image.png 初始化的流程如下 image.png postProcessBeforeInitialization方法在调用初始化方法之前执行,让用户可以不断的包装对象,有一个返回了null,则结束循环 image.png 返回对象之后就执行初始化方法,InitializingBean的方法就是在这里被触发 image.png 执行完初始化方法之后,spring会调用postProcessBeforeInitialization的另一个生命周期方法,同样也是让用户可以包装几层