SpringBoot扩展点——一文掌握BeanPostProcessor家族

简介: SpringBoot扩展点——一文掌握BeanPostProcessor家族

概述


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


BeanPostProcessor家族介绍


1671108457018.jpg

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
@Data
@Slf4j
public class BeanLifeCycle {
    private String prop ;
    public BeanLifeCycle() {
        log.info("#################BeanLifeCycle 实例化");
    }
    public void init() {
        log.info("#################BeanLifeCycle 初始化");
    }
    public void destroy() {
        log.info("#################BeanLifeCycle 销毁");
    }
}
@Configuration
public class LifeCycleConfig {
    @Bean(name = "beanLifeCycle", initMethod = "init", destroyMethod = "destroy")
    public BeanLifeCycle createBeanLifeCycle() {
        BeanLifeCycle beanLifeCycle = new BeanLifeCycle();
        return beanLifeCycle;
    }
}
  1. 创建InstantiationAwareBeanPostProcessor
@Component
@Slf4j
public class TestInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        if("beanLifeCycle".equals(beanName)) {
            log.info("################InstantiationAwareBeanPostProcessor before instant: [{}]", beanName);
            // 如果返回一个bean,则后续只会调用BeanPostProcessor的 postProcessAfterInitialization方法
            //return new BeanLifeCycle().setProp("aaa");
        }
        // 如果返回null,正常实例化
        return null;
    }
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if("beanLifeCycle".equals(beanName)) {
            log.info("################InstantiationAwareBeanPostProcessor after instant: bean: [{}], beanName: [{}]", bean, beanName);
        }
        // 返回true,表示Bean属性需要被赋值,否则不会
        return true;
    }
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if("beanLifeCycle".equals(beanName)) {
            log.info("################InstantiationAwareBeanPostProcessor postProcessProperties: pvs: [{}], bean: [{}], beanName: [{}]", pvs, bean, beanName);
        }
        return pvs;
    }
}
  1. 创建普通的BeanPostProcessor
@Component
@Slf4j
public class TestBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if("beanLifeCycle".equals(beanName)) {
            log.info("################BeanPostProcessor before init: bean:[{}], beanName: [{}]", bean, beanName);
        }
        return bean;
    }
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if("beanLifeCycle".equals(beanName)) {
            log.info("################BeanPostProcessor after init: bean:[{}], beanName: [{}]", bean, beanName);
        }
        return bean;
    }
}
  1. 创建DestructionAwareBeanPostProcessor
@Slf4j
@Component
public class TestDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
    @Override
    public void postProcessBeforeDestruction(Object obj, String beanName) throws BeansException {
        if("beanLifeCycle".equals(beanName)) {
            log.info("################DestructionAwareBeanPostProcessor before destroy: bean:[{}], beanName: [{}]", obj, beanName);
        }
    }
    @Override
    public boolean requiresDestruction(Object bean) {
        if(bean instanceof BeanLifeCycle) {
            log.info("################DestructionAwareBeanPostProcessor requiresDestruction: bean:[{}]", bean);
        }
        // true表示销毁, false表示不销毁,也不会执行postProcessBeforeDestruction方法了
        return true;
    }
}
  1. 执行结果

1671108524202.jpg

如图所示执行结果,得出结论如下:

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

代码地址:github.com/alvinlkk/sp…


源码解析


源码解析这块我们重点主要关注在InstantiationAwareBeanPostProcessorBeanPostProcessor这两个相对比较中的扩展点。

以上的扩展接口都是围绕着Bean的创建,而Bean创建的入口AbstractAutowireCapableBeanFactorycreateBean方法:

@Override
  protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
    if (logger.isTraceEnabled()) {
      logger.trace("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;
    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
    }
    // Prepare method overrides.
    try {
      mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
          beanName, "Validation of method overrides failed", ex);
    }
    try {
      // resolveBeforeInstantiation方法主要是给InstantiationAwareBeanPostProcessor后置处理器一个Bean实例代理的机会.
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      // 如果返回的不为空,说明已经实例化了,则直接返回,为空的话,继续走下面的正常流程doCreateBean
            if (bean != null) {
        return bean;
      }
    }
    catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
          "BeanPostProcessor before instantiation of bean failed", ex);
    }
    try {
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
        logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
    }
    catch (Throwable ex) {
      throw new BeanCreationException(
          mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
  }

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

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

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

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
    // Instantiate the bean.实例化bean开始
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
            // 实例化bean
      instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
      mbd.resolvedTargetType = beanType;
    }
        // 实例化bean结束
    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
        try {
          applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        }
        catch (Throwable ex) {
          throw new BeanCreationException(mbd.getResourceDescription(), beanName,
              "Post-processing of merged bean definition failed", ex);
        }
        mbd.postProcessed = true;
      }
    }
    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
      if (logger.isTraceEnabled()) {
        logger.trace("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
      }
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
            // 为bean属性赋值
      populateBean(beanName, mbd, instanceWrapper);
            // 初始化bean
      exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
        .......
  }

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

populateBean方法代码如下:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
      .....
        // 获取所有的InstantiationAwareBeanPostProcessor 
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
        // 调用postProcessAfterInstantiation方法,如果返回false, 则populateBean方法直接返回,后续赋值操作不再进行
                if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
          return;
        }
      }
    }
       // 开始为属性赋值,比如@Autowired注解的
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    int resolvedAutowireMode = mbd.getResolvedAutowireMode();
    if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
      // Add property values based on autowire by name if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
        autowireByName(beanName, mbd, bw, newPvs);
      }
      // Add property values based on autowire by type if applicable.
      if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
        autowireByType(beanName, mbd, bw, newPvs);
      }
      pvs = newPvs;
    }
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    PropertyDescriptor[] filteredPds = null;
    if (hasInstAwareBpps) {
      if (pvs == null) {
        pvs = mbd.getPropertyValues();
      }
      for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
        PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
        if (pvsToUse == null) {
          if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
          }
          pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
          if (pvsToUse == null) {
            return;
          }
        }
        pvs = pvsToUse;
      }
    }
    if (needsDepCheck) {
      if (filteredPds == null) {
        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      }
      checkDependencies(beanName, mbd, filteredPds, pvs);
    }
    if (pvs != null) {
      applyPropertyValues(beanName, mbd, bw, pvs);
    }
  }

接着查看initializeBean方法源码:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
      AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
        invokeAwareMethods(beanName, bean);
        return null;
      }, getAccessControlContext());
    }
    else {
      invokeAwareMethods(beanName, bean);
    }
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
            // 执行BeanPostProcessor的postProcessBeforeInitialization初始化前置处理器
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    try {
            //执行初始化操作
      invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
      throw new BeanCreationException(
          (mbd != null ? mbd.getResourceDescription() : null),
          beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
            // 执行BeanPostProcessor的postProcessBeforeInitialization初始化后置处理器
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }
    return wrappedBean;
  }

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

1671108558017.jpg


目录
相关文章
|
7月前
|
前端开发 Java 应用服务中间件
Springboot对MVC、tomcat扩展配置
Springboot对MVC、tomcat扩展配置
|
1月前
|
Java 开发者 Spring
精通SpringBoot:16个扩展接口精讲
【10月更文挑战第16天】 SpringBoot以其简化的配置和强大的扩展性,成为了Java开发者的首选框架之一。SpringBoot提供了一系列的扩展接口,使得开发者能够灵活地定制和扩展应用的行为。掌握这些扩展接口,能够帮助我们写出更加优雅和高效的代码。本文将详细介绍16个SpringBoot的扩展接口,并探讨它们在实际开发中的应用。
46 1
|
2月前
|
监控 Java 开发者
掌握SpringBoot扩展接口:提升代码优雅度的16个技巧
【10月更文挑战第20天】 SpringBoot以其简化配置和快速开发而受到开发者的青睐。除了基本的CRUD操作外,SpringBoot还提供了丰富的扩展接口,让我们能够更灵活地定制和扩展应用。以下是16个常用的SpringBoot扩展接口,掌握它们将帮助你写出更加优雅的代码。
79 0
|
4月前
|
Java 开发者 Spring
"揭秘SpringBoot魔法SPI机制:一键解锁服务扩展新姿势,让你的应用灵活飞天!"
【8月更文挑战第11天】SPI(Service Provider Interface)是Java的服务提供发现机制,用于运行时动态查找和加载服务实现。SpringBoot在其基础上进行了封装和优化,通过`spring.factories`文件提供更集中的配置方式,便于框架扩展和组件替换。本文通过定义接口`HelloService`及其实现类`HelloServiceImpl`,并在`spring.factories`中配置,结合`SpringFactoriesLoader`加载服务,展示了SpringBoot SPI机制的工作流程和优势。
63 5
|
6月前
|
监控 Java 应用服务中间件
Spring Boot应用的部署与扩展
Spring Boot应用的部署与扩展
|
5月前
|
监控 Java 应用服务中间件
Spring Boot应用的部署与扩展
Spring Boot应用的部署与扩展
|
6月前
|
存储 Java Apache
整合Spring Boot和Pulsar实现可扩展的消息处理
整合Spring Boot和Pulsar实现可扩展的消息处理
|
7月前
|
XML 设计模式 Java
springboot创建并配置环境3 - 配置扩展属性(下)
springboot创建并配置环境3 - 配置扩展属性(下)
springboot创建并配置环境3 - 配置扩展属性(下)
|
7月前
|
XML JSON Java
springboot如何创建并配置环境3 - 配置扩展属性(上)
springboot如何创建并配置环境3 - 配置扩展属性(上)
springboot如何创建并配置环境3 - 配置扩展属性(上)
|
7月前
|
前端开发 Java
Springboot对SpringMVC如何扩展配置
Springboot对SpringMVC如何扩展配置