BeanPostProcessor的概念容易与BeanFactoryPostProcessor的概念混淆,看上去都是以PostProcessor,但两者不是同一个概念,用处也不同;BeanPostProcessor是存在于对象实例化后,进行初始化的阶段BeanFactoryPostProcessor则是存在于容器启动阶段;

 

BeanPostProcessor为bean的后置处理器,在bean初始化之前调用进行拦截,在bean初始化前后进行一些处理工作 ,说明此时的bean已经进行了实例化;

 

BeanPostProcessor接口声明了两个方法,分别在两个不同的时机执行;BeanPostProcessor的两个方法中都传入了原来的对象实例的引用,这为使用者扩展容器的对象实例化过程中的行为提供了极大的便利,使用者几乎可以对传入的对象实例执行任何的操作;

 

以下Spring版本为5.2.4.RELEASE


org.springframework.context.support.AbstractApplicationContext#refresh是Spring中一个很重要的方法,它用来加载配置,完成Spring上下文初始化工作,而refresh方法在org.springframework.context.ConfigurableApplicationContext接口定义;

Spring BeanPostProcessor分析

 

  • org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization

  Spring BeanPostProcessor分析

  postProcessBeforeInitialization方法是BeanPostProcessor前置处理这一步将会执行的方法,该方法会在org.springframework.beans.factory.InitializingBean#afterPropertiesSet或自定义init-method方法执行;

  org.springframework.beans.factory.InitializingBean#afterPropertiesSet,在初始化bean的时候执行,可以针对某个具体的bean进行自定义配置;

  Spring BeanPostProcessor分析

 

    不过afterPropertiesSet方法是优先于init-method执行;

 

  init-method方式有两种,如下;

    • @Bean注解的initMethod属性添加该类自定义的初始化方法;  

      org.springframework.context.annotation.Bean#initMethod

    Spring BeanPostProcessor分析

 

    • Spring支持 JSR-250,可在该类自定义的初始化方法上添加@PostConstruct注解

      @PostConstruct:在bean创建完成(即在构造方法执行完毕后执行),且属于赋值完成后进行初始化,属于JDK规范的注解;
      @PreDestroy:在bean将被移除之前进行通知,在容器销毁之前进行清理工作;

      这两个注解org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor是在这里进行处理的;

    Spring BeanPostProcessor分析

    参考:[https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-lifecycle]   

   

      • @PostConstruct@PreDestroy的解析过程

        @PostConstruct是处理对象的初始化,也就是说,在此之前对象已经实例化完成了;如下图中AbstractAutowireCapableBeanFactory#doCreateBeancreateBeanInstance处理对象实例化已经完成了,而之后会调用applyMergedBeanDefinitionPostProcessors,找到MergedBeanDefinitionPostProcessor类型的后置处理器,让后置处理器修改beanDefinition,缓存一些注解信息;

      Spring BeanPostProcessor分析

 

        AnnotationConfigUtils中为容器注册处理JSR规范的注解处理器CommonAnnotationBeanPostProcessorbeanDefinition

        AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)

      Spring BeanPostProcessor分析

 

        CommonAnnotationBeanPostProcessorInitDestroyAnnotationBeanPostProcessor的关系图,如下;

        Spring BeanPostProcessor分析

  

        在CommonAnnotationBeanPostProcessor的构造器中设置了initAnnotationTypedestroyAnnotationType的注解类型;

        Spring BeanPostProcessor分析

 

        applyMergedBeanDefinitionPostProcessors调用的是CommonAnnotationBeanPostProcessor#postProcessMergedBeanDefinitionCommonAnnotationBeanPostProcessor继承了InitDestroyAnnotationBeanPostProcessor,最终会回调到InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition,如下图;

        Spring BeanPostProcessor分析

 

        InitDestroyAnnotationBeanPostProcessor#postProcessMergedBeanDefinition最终会调用到InitDestroyAnnotationBeanPostProcessor#buildLifecycleMetadata,它会构建生命周期元数据(解析@PostConstruct@PreDestroy注解),当其构造完成后会将元数据缓存到lifecycleMetadata,此时就完成了相关方法(初始化方法和销毁方法)的扫描解析和缓存;   

        Spring BeanPostProcessor分析

 

 

 

  • org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization

  Spring BeanPostProcessor分析

   postProcessAfterInitialization方法是BeanPostProcessor后置处理那一步将会执行的方法,该方法会在org.springframework.beans.factory.InitializingBean#afterPropertiesSet自定义init-method方法执行;

  具体调用,如下

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

  bean在实例化后,进入初始化阶段;

  Spring BeanPostProcessor分析

 

  org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods 

  该方法里面会有调用afterPropertiesSetinvokeCustomInitMethod

  afterPropertiesSet方法对实现了InitializingBean接口的类可以进行自定义初始化配置,在构造方法执行;

  invokeCustomInitMethod也是可以进行自定义初始化配置,在构造方法执行,不需要实现InitializingBean接口;

  自定义的init-method是在org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod设置的;

  Spring BeanPostProcessor分析

  该方法是在org.springframework.context.support.AbstractApplicationContext#invokeBeanFactoryPostProcessors里面进行调用的,里面执行的是执行BeanFactoryPostProcessor的方法;

 

  @PostConstruct优先于afterPropertiesSetinit-method执行;

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

  Spring BeanPostProcessor分析

  applyBeanPostProcessorsBeforeInitialization处理@PostConstruct,而后面的invokeInitMethods处理的是afterPropertiesSetinit-method

  applyBeanPostProcessorsBeforeInitialization最终会调用到InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization,获取之前缓存注解元数据的LifecycleMetadata,通过LifecycleMetadata获取注解映射的方法,之后进行反射调用;

  InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization

  Spring BeanPostProcessor分析

 

  前面说到afterPropertiesSet方法执行优先于init-method,具体如下;

  Spring BeanPostProcessor分析

 

  而invokeCustomInitMethod里面调用的是BeanDefinitioninit-method方法;

  Spring BeanPostProcessor分析

 

   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

   该方法在自定义初始化配置执行;遍历对应的Processors,并执行它相应的postProcessorsBeforeInitialization方法;

   Spring BeanPostProcessor分析

 

  org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

  该方法在自定义初始化配置执行;遍历对应的Processors,并执行它相应的postProcessorsAfterInitialization方法;

  Spring BeanPostProcessor分析

 

  它的调用格式如下,这个相当于AOP,在invokeInitMethods的前后进行方法增强;

applyBeanPostProcessorsBeforeInitialization

invokeInitMethods

applyBeanPostProcessorsAfterInitialization

 

  • 测试代码
@Configuration
public class InitConfig {
	@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
	public Person person() {
		return new Person();
	}
}

  

public class Person implements InitializingBean {
	private final static Log LOG = LogFactory.getLog(Person.class);

	@Override
	public void afterPropertiesSet() throws Exception {
		LOG.info("afterPropertiesSet");
	}

	@PostConstruct
	public void init() {
		LOG.info("PostConstruct init");
	}

	@PreDestroy
	public void preDestroy() {
		LOG.info("PreDestroy");
	}

	public void initMethod() {
		LOG.info("init-method");
	}

	public void destroyMethod() {
		LOG.info("destroy");
	}
}

  

@Test
public void initMethodTest() {
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
    ctx.register(InitConfig.class);
    ctx.refresh();
    Assertions.assertNotNull(ctx.getBean(Person.class));
    ctx.close();
}

  

  测试结果如下:

Spring BeanPostProcessor分析

 

BeanPostProcessor一些扩展接口整理

Spring BeanPostProcessor分析

 

  • InstantiationAwareBeanPostProcessor

Spring BeanPostProcessor分析

  postProcessBeforeInstantiation:可用于bean实例前进行回调;

  postProcessAfterInstantiation:可用于bean实例后进行回调;

 

  • MergedBeanDefinitionPostProcessor

Spring BeanPostProcessor分析

  postProcessMergedBeanDefinition:可用于找到所有需要注入的字段,同时做缓存,如缓存注解信息;

  resetBeanDefinition:可用于在beanDefinition被修改后,清除容器的缓存;

 

  • DestructionAwareBeanPostProcessor

Spring BeanPostProcessor分析

  postProcessBeforeDestruction:可用于bean被销毁前调用;

  requiresDestruction:可用于判断是否要进行销毁,一般情况都是需要的;

 

  • SmartInstantiationAwareBeanPostProcessor

Spring BeanPostProcessor分析

  predictBeanType:可用于预测bean的类型,主要是在bean还没创建前需要获取bean的类型;

  determineCandidateConstructors:可用于完成对构造方法的解析和推断,获取构造器;

  getEarlyBeanReference:可用于解决循环依赖问题,通过此方法提前暴露早期对象;

 

相关文章: