BeanFactoryPostProcessor,BeanPostProcessor,SmartInitializingSingleton等几个可拓展接口的执行时机

基于springboot2.1.4

1、BeanFactoryPostProcessor
主要用于对beanDefinition的修改,对beanFactory中的相关参数进行修改
eg:org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanFactory

在执行org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors之前,可以在创建context后通过listener、initializer等方式手动new一个BeanFactoryPostProcessor的实现类,然后put入context的org.springframework.context.support.AbstractApplicationContext#beanFactoryPostProcessors中。

在执行invokeBeanFactoryPostProcessors的时候,首先从context中获取到前面手动new然后put入的BeanFactoryPostProcessors

在invokeBeanFactoryPostProcessors方法中,首先是对BeanDefinitionRegistryPostProcessor类型的processor进行处理

当通过beandefinition查找时,beanDefinition可能通过代码手动添加,或者通过扫描注解添加,此时都会提前实例化。这些通过beandefinition实例化的bean不会加入到context的beanFactoryPostProcessors列表中。

在处理完BeanDefinitionRegistryPostProcessor后,接下来处理非BeanDefinitionRegistryPostProcessor的beanFactoryPostProcessor
操作跟通过beandefinition实例化的BeanDefinitionRegistryPostProcessor过程基本类似,也是先查找beandefinition,然后实例化,然后执行postProcessBeanFactory方法。
自定义demo如下:

2、BeanPostProcessor
主要用于bean实例化的前置后置处理eg:org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor

BeanPostProcessor保存在ConfigurableListableBeanFactory中,通过beandefinition定义的会在org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors-->org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors()提前实例化并添加到BeanFactory中,如果通过new BeanPostProcessor实现类然后手动添加到BeanFactory,则需要在实例化bean执行org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization前,保证需要的BeanPostProcessor已经添加到BeanFactory。
过程跟1中的invokeBeanFactoryPostProcessors类似,不做过多描述
前置后置方法执行时机

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean-->org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)

不过需要注意的是有些BeanPostProcessor是实现了MergedBeanDefinitionPostProcessor或者InstantiationAwareBeanPostProcessor(这两个接口也是继承了BeanPostProcessor接口),在执行前置后置方法时,如果不清楚一些变量从何而来,可以尝试从这两个接口特有的实现方法中找。自定义demo如下:

3、SmartInitializingSingleton
在所有的单例实例化完之后,对满足条件的实例做后续处理eg:org.springframework.context.event.EventListenerMethodProcessor

在org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons中,所有的beanDefinition实例化完之后,才开始查找其中实现了SmartInitializingSingleton接口的实例,因此只要使用注解生成SmartInitializingSingleton实现类实例就可以了

自定义demo
/**
 * 参考org.springframework.context.event.EventListenerMethodProcessor
 */

@Component
public class AnnoCustomBeanSingletonProcessor implements SmartInitializingSingleton {
    @Override
    public void afterSingletonsInstantiated() {
        System.out.println("AnnoCustomBeanSingletonProcessor afterSingletonsInstantiated");
    }
}

4、MergedBeanDefinitionPostProcessor
5、InstantiationAwareBeanPostProcessor
除了BeanPostProcessor的两个接口方法外还有如下两个接口,在实例化后初始化前,完成成员变量的填充
postProcessProperties(PropertyValues pvs, Object bean, String beanName)
postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
6、Aware接口
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
在bean填充完成员变量之后,在bean初始化时先完成几个Aware接口的回调((BeanNameAware) bean).setBeanName(beanName);、((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);、((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
7、org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor
继承自InstantiationAwareBeanPostProcessor
可用于自定义检测构造方法等Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本来是准备看一看Spring源码的。然后在知乎上看到来一个帖子,说有一群**自己连Spring官方文档都没有完全读...
    此鱼不得水阅读 6,967评论 4 21
  • 2.1 我们的理念是:让别人为你服务 IoC是随着近年来轻量级容器(Lightweight Container)的...
    好好学习Sun阅读 2,760评论 0 11
  • 前面写过一篇Spring扩展的文章 Spring扩展点1-NameSpaceHandler,本来想写系列文章,可是...
    一帅阅读 11,129评论 6 19
  • 0x01 IoC 容器服务提供者-BeanFactory 在开始之前,我们需要知道Spring IoC容器和IoC...
    现实目标决心阅读 455评论 0 1
  • MySQL的几个常用安装包:rpm、源码、二进制免编译 的区别? 一般用,二进制免编译,二进制包括了已经经过编译,...
    AMZ小楼阅读 127评论 0 0