概述

本文主要讲解下SpringBoot的一个关键扩展点BeanPostProcessor, 他有很多的子接口,这里我们一并做了一个介绍。

BeanPostProcessor家族介绍

image.png
BeanPostProcessor处理器分别在Bean生命周期的不同阶段起作用,Bean的实例化阶段先于Bean初始化阶段,最后是Bean的销毁阶段,主要规类如下:

Bean实例化阶段

在Spring Bean生命周期中,Bean实例化指的是创建Bean的过程, 此时Bean的属性还没有赋值。

1. InstantiationAwareBeanPostProcessor

作用:BeanPostProcessor的子接口,它可以在实例化之前回调,也可以在实例化之后但是属性设置或者自动装配发生之前回调。
使用场景:可以用来修改特定Bean默认的实例化,比如创建代理类,或者实现额外的注册策略。
接口方法:
1). Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)

  • 在目标bean被实例化之前调用,返回值是Object类型,可以返回目标实例的一个代理用来代替目标实例。
  • 返回值如果不是null, 后续不会再进行实例化,只会执行postProcessAfterInitialization这个回调,其他方法不调用。否则按照正常的流程走。

2). boolean postProcessAfterInstantiation(Object bean, String beanName)

  • 在目标对象被实例化后并且属性值还没有被设置的时候调用。
  • 返回值是boolean类型,返回true时,表示Bean属性需要被赋值;返回false表示跳过Bean属性赋值,并且InstantiationAwareBeanPostProcessor的postProcessProperties方法不会被调用。

3). PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)

  • 方法的作用在属性中被设置到目标实例之前调用,对属性值进行修改。

    2. SmartInstantiationAwareBeanPostProcessor

    作用:继承于InstantiationAwareBeanPostProcessor接口,主要作用也是在于目标对象的实例化过程中需要处理的事情。它是InstantiationAwareBeanPostProcessor接口的一个扩展。主要在Spring框架内部使用,不是重点。
    接口方法:
    1). Class<?> predictBeanType(Class<?> beanClass, String beanName)

  • 用于预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null。主要在于BeanDefinition无法确定Bean类型的时候调用该方法来确定类型。

2). Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)

  • 用于选择合适的构造器,比如类有多个构造器,可以实现这个方法选择合适的构造器并用于实例化对象。
  • 该方法在postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法之间调用,如果postProcessBeforeInstantiation方法返回了一个新的实例代替了原本该生成的实例,那么该方法会被忽略。

3). Object getEarlyBeanReference(Object bean, String beanName)

  • getEarlyBeanReference主要用于解决循环引用问题。比如ReferenceA实例内部有ReferenceB的引用,ReferenceB实例内部有ReferenceA的引用。首先先实例化ReferenceA,实例化完成之后提前把这个bean暴露在ObjectFactory中,然后populate属性,这个时候发现需要ReferenceB。然后去实例化ReferenceB,在实例化ReferenceB的时候它需要ReferenceA的实例才能继续,这个时候就会去ObjectFactory中找出了ReferenceA实例,ReferenceB顺利实例化。ReferenceB实例化之后,ReferenceA的populate属性过程也成功完成,注入了ReferenceB实例。提前把这个bean暴露在ObjectFactory中,这个ObjectFactory获取的实例就是通过getEarlyBeanReference方法得到的。

    Bean初始化阶段

    Bean初始化阶段是指Bean创建后,对其属性进行赋值(populate bean)、后置处理等操作的过程。

    1. MergedBeanDefinitionPostProcessor

    作用:继承BeanPostProcessor, 在合并Bean定义之后调用。
    接口方法:
    1). postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)

  • 该方法是在合并Bean定义之后调用。

    2. BeanPostProcessor

    作用:该方法是核心方法,主要是在Bean初始化前后调用。
    接口方法:
    1).Object postProcessBeforeInitialization(Object bean, String beanName)

  • 在bean初始化之前调用的方法

2).Object postProcessAfterInitialization(Object bean, String beanName)

  • 在bean初始化之后调用的方法

    Bean销毁阶段

    1. DestructionAwareBeanPostProcessor

    作用:继承BeanPostProcessor接口,Bean在容器被销毁之前调用
    接口方法:
    1).postProcessBeforeDestruction(Object bean, String beanName)

  • bean在销毁之前调用

2).boolean requiresDestruction(Object bean)

  • 在bean销毁之前调用,决定bean是否要被销毁
  • 返回值未boolean类型,如果返回true,则先调用postProcessBeforeDestruction回调,如果返回false, 不进行销毁。

    实战演练

  1. 定义Bean ```java @Data @Slf4j public class BeanLifeCycle {

    private String prop ;

    public BeanLifeCycle() {

    1. log.info("#################BeanLifeCycle 实例化");

    }

    public void init() {

    1. log.info("#################BeanLifeCycle 初始化");

    }

    public void destroy() {

    1. log.info("#################BeanLifeCycle 销毁");

    } }

  1. ```java
  2. @Configuration
  3. public class LifeCycleConfig {
  4. @Bean(name = "beanLifeCycle", initMethod = "init", destroyMethod = "destroy")
  5. public BeanLifeCycle createBeanLifeCycle() {
  6. BeanLifeCycle beanLifeCycle = new BeanLifeCycle();
  7. return beanLifeCycle;
  8. }
  9. }
  1. 创建InstantiationAwareBeanPostProcessor ```java @Component @Slf4j public class TestInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

    @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

    1. if("beanLifeCycle".equals(beanName)) {
    2. log.info("################InstantiationAwareBeanPostProcessor before instant: [{}]", beanName);
    3. // 如果返回一个bean,则后续只会调用BeanPostProcessor的 postProcessAfterInitialization方法
    4. //return new BeanLifeCycle().setProp("aaa");
    5. }
    6. // 如果返回null,正常实例化
    7. return null;

    }

    @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {

    1. if("beanLifeCycle".equals(beanName)) {
    2. log.info("################InstantiationAwareBeanPostProcessor after instant: bean: [{}], beanName: [{}]", bean, beanName);
    3. }
    4. // 返回true,表示Bean属性需要被赋值,否则不会
    5. return true;

    }

    @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {

    1. if("beanLifeCycle".equals(beanName)) {
    2. log.info("################InstantiationAwareBeanPostProcessor postProcessProperties: pvs: [{}], bean: [{}], beanName: [{}]", pvs, bean, beanName);
    3. }
    4. return pvs;

    } }

  1. 3. 创建普通的`BeanPostProcessor`
  2. ```java
  3. @Component
  4. @Slf4j
  5. public class TestBeanPostProcessor implements BeanPostProcessor {
  6. @Override
  7. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  8. if("beanLifeCycle".equals(beanName)) {
  9. log.info("################BeanPostProcessor before init: bean:[{}], beanName: [{}]", bean, beanName);
  10. }
  11. return bean;
  12. }
  13. @Override
  14. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  15. if("beanLifeCycle".equals(beanName)) {
  16. log.info("################BeanPostProcessor after init: bean:[{}], beanName: [{}]", bean, beanName);
  17. }
  18. return bean;
  19. }
  20. }
  1. 创建DestructionAwareBeanPostProcessor

    1. @Slf4j
    2. @Component
    3. public class TestDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
    4. @Override
    5. public void postProcessBeforeDestruction(Object obj, String beanName) throws BeansException {
    6. if("beanLifeCycle".equals(beanName)) {
    7. log.info("################DestructionAwareBeanPostProcessor before destroy: bean:[{}], beanName: [{}]", obj, beanName);
    8. }
    9. }
    10. @Override
    11. public boolean requiresDestruction(Object bean) {
    12. if(bean instanceof BeanLifeCycle) {
    13. log.info("################DestructionAwareBeanPostProcessor requiresDestruction: bean:[{}]", bean);
    14. }
    15. // true表示销毁, false表示不销毁,也不会执行postProcessBeforeDestruction方法了
    16. return true;
    17. }
    18. }

    �5. 执行结果
    image.png
    如图所示执行结果,得出结论如下:

  2. InstantiationAwareBeanPostProcessor是在类的实例化前后进行回调,如上图序号的1,3,4

  3. BeanPostProcessor是在类的初始化前后进行回调,如上图中的5,7

代码地址:https://github.com/alvinlkk/springboot-demo/tree/master/springboot-bean-lifecycle

源码解析

源码解析这块我们重点主要关注在InstantiationAwareBeanPostProcessorBeanPostProcessor这两个相对比较中的扩展点。
以上的扩展接口都是围绕着Bean的创建,而Bean创建的入口AbstractAutowireCapableBeanFactorycreateBean方法:

  1. @Override
  2. protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  3. throws BeanCreationException {
  4. if (logger.isTraceEnabled()) {
  5. logger.trace("Creating instance of bean '" + beanName + "'");
  6. }
  7. RootBeanDefinition mbdToUse = mbd;
  8. // Make sure bean class is actually resolved at this point, and
  9. // clone the bean definition in case of a dynamically resolved Class
  10. // which cannot be stored in the shared merged bean definition.
  11. Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
  12. if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
  13. mbdToUse = new RootBeanDefinition(mbd);
  14. mbdToUse.setBeanClass(resolvedClass);
  15. }
  16. // Prepare method overrides.
  17. try {
  18. mbdToUse.prepareMethodOverrides();
  19. }
  20. catch (BeanDefinitionValidationException ex) {
  21. throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
  22. beanName, "Validation of method overrides failed", ex);
  23. }
  24. try {
  25. // resolveBeforeInstantiation方法主要是给InstantiationAwareBeanPostProcessor后置处理器一个Bean实例代理的机会.
  26. Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
  27. // 如果返回的不为空,说明已经实例化了,则直接返回,为空的话,继续走下面的正常流程doCreateBean
  28. if (bean != null) {
  29. return bean;
  30. }
  31. }
  32. catch (Throwable ex) {
  33. throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
  34. "BeanPostProcessor before instantiation of bean failed", ex);
  35. }
  36. try {
  37. Object beanInstance = doCreateBean(beanName, mbdToUse, args);
  38. if (logger.isTraceEnabled()) {
  39. logger.trace("Finished creating instance of bean '" + beanName + "'");
  40. }
  41. return beanInstance;
  42. }
  43. catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
  44. // A previously detected exception with proper bean creation context already,
  45. // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
  46. throw ex;
  47. }
  48. catch (Throwable ex) {
  49. throw new BeanCreationException(
  50. mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
  51. }
  52. }

参考上面源码中的注释,我们重点关注resolveBeforeInstantiation方法。

  1. @Nullable
  2. protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  3. Object bean = null;
  4. // beforeInstantiationResolved属性值默认为false, 如果bean实例前置操作还未执行
  5. if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
  6. // Make sure bean class is actually resolved at this point.
  7. // 判断是否有InstantiationAwareBeanPostProcessor处理器
  8. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  9. Class<?> targetType = determineTargetType(beanName, mbd);
  10. if (targetType != null) {
  11. // 执行InstantiationAwareBeanPostProcessor处理器中的postProcessBeforeInstantiation方法
  12. bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
  13. if (bean != null) {
  14. // 如果bean已经被上述的前置处理器实例化了,
  15. // 则跳过其他步骤,直接执行BeanPostProcessor处理器中的postProcessAfterInitialization方法进行初始化
  16. bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
  17. }
  18. }
  19. }
  20. // 如果bean不为null,设置beforeInstantiationResolved属性值为true
  21. mbd.beforeInstantiationResolved = (bean != null);
  22. }
  23. return bean;
  24. }

如果没有对bean进行代理增量,返回null的情况,则走标准的流程,执行后面的doCreateBean方法。�

  1. protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
  2. throws BeanCreationException {
  3. // Instantiate the bean.实例化bean开始
  4. BeanWrapper instanceWrapper = null;
  5. if (mbd.isSingleton()) {
  6. instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
  7. }
  8. if (instanceWrapper == null) {
  9. // 实例化bean
  10. instanceWrapper = createBeanInstance(beanName, mbd, args);
  11. }
  12. Object bean = instanceWrapper.getWrappedInstance();
  13. Class<?> beanType = instanceWrapper.getWrappedClass();
  14. if (beanType != NullBean.class) {
  15. mbd.resolvedTargetType = beanType;
  16. }
  17. // 实例化bean结束
  18. // Allow post-processors to modify the merged bean definition.
  19. synchronized (mbd.postProcessingLock) {
  20. if (!mbd.postProcessed) {
  21. try {
  22. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
  23. }
  24. catch (Throwable ex) {
  25. throw new BeanCreationException(mbd.getResourceDescription(), beanName,
  26. "Post-processing of merged bean definition failed", ex);
  27. }
  28. mbd.postProcessed = true;
  29. }
  30. }
  31. // Eagerly cache singletons to be able to resolve circular references
  32. // even when triggered by lifecycle interfaces like BeanFactoryAware.
  33. boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
  34. isSingletonCurrentlyInCreation(beanName));
  35. if (earlySingletonExposure) {
  36. if (logger.isTraceEnabled()) {
  37. logger.trace("Eagerly caching bean '" + beanName +
  38. "' to allow for resolving potential circular references");
  39. }
  40. addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
  41. }
  42. // Initialize the bean instance.
  43. Object exposedObject = bean;
  44. try {
  45. // 为bean属性赋值
  46. populateBean(beanName, mbd, instanceWrapper);
  47. // 初始化bean
  48. exposedObject = initializeBean(beanName, exposedObject, mbd);
  49. }
  50. .......
  51. }

重点关注这里的populateBeaninitializeBean方法,后置处理器就是在这两个方法中起作用。
populateBean方法代码如下:

  1. protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
  2. .....
  3. // 获取所有的InstantiationAwareBeanPostProcessor
  4. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
  5. for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
  6. // 调用postProcessAfterInstantiation方法,如果返回false, 则populateBean方法直接返回,后续赋值操作不再进行
  7. if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
  8. return;
  9. }
  10. }
  11. }
  12. // 开始为属性赋值,比如@Autowired注解的
  13. PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
  14. int resolvedAutowireMode = mbd.getResolvedAutowireMode();
  15. if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  16. MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
  17. // Add property values based on autowire by name if applicable.
  18. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
  19. autowireByName(beanName, mbd, bw, newPvs);
  20. }
  21. // Add property values based on autowire by type if applicable.
  22. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
  23. autowireByType(beanName, mbd, bw, newPvs);
  24. }
  25. pvs = newPvs;
  26. }
  27. boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
  28. boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
  29. PropertyDescriptor[] filteredPds = null;
  30. if (hasInstAwareBpps) {
  31. if (pvs == null) {
  32. pvs = mbd.getPropertyValues();
  33. }
  34. for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
  35. PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
  36. if (pvsToUse == null) {
  37. if (filteredPds == null) {
  38. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  39. }
  40. pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
  41. if (pvsToUse == null) {
  42. return;
  43. }
  44. }
  45. pvs = pvsToUse;
  46. }
  47. }
  48. if (needsDepCheck) {
  49. if (filteredPds == null) {
  50. filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
  51. }
  52. checkDependencies(beanName, mbd, filteredPds, pvs);
  53. }
  54. if (pvs != null) {
  55. applyPropertyValues(beanName, mbd, bw, pvs);
  56. }
  57. }

接着查看initializeBean方法源码:

  1. protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
  2. if (System.getSecurityManager() != null) {
  3. AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
  4. invokeAwareMethods(beanName, bean);
  5. return null;
  6. }, getAccessControlContext());
  7. }
  8. else {
  9. invokeAwareMethods(beanName, bean);
  10. }
  11. Object wrappedBean = bean;
  12. if (mbd == null || !mbd.isSynthetic()) {
  13. // 执行BeanPostProcessor的postProcessBeforeInitialization初始化前置处理器
  14. wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
  15. }
  16. try {
  17. //执行初始化操作
  18. invokeInitMethods(beanName, wrappedBean, mbd);
  19. }
  20. catch (Throwable ex) {
  21. throw new BeanCreationException(
  22. (mbd != null ? mbd.getResourceDescription() : null),
  23. beanName, "Invocation of init method failed", ex);
  24. }
  25. if (mbd == null || !mbd.isSynthetic()) {
  26. // 执行BeanPostProcessor的postProcessBeforeInitialization初始化后置处理器
  27. wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
  28. }
  29. return wrappedBean;
  30. }

上面我们通过源码的角度,针对关键的InstantiationAwareBeanPostProcessorBeanPostProcessor两个接口做了一个分析,在源码阅读的时候,可以打上断点,一步一步调试,整体的一个执行流程如下图所示:
image.png

参考

https://fangjian0423.github.io/2017/06/20/spring-bean-post-processor/
https://mrbird.cc/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3Spring-BeanPostProcessor-InstantiationAwareBeanPostProcessor.html