Spring后置处理器中的InstantiationAwareBeanPostProcessor详解

简介: Spring后置处理器中的InstantiationAwareBeanPostProcessor详解

其是BeanPostProcessor的子接口,增加了before-instantiation回调,以及在postProcessAfterInstantiation(bean实例化后但是确切属性设置/autowire注入发生)前增加了postProcessAfterInstantiation回调。


通常用于抑制特定目标bean的默认实例化,例如AbstractAutoProxyCreator创建具有特殊TargetSources的代理(池目标、延迟初始化目标等),或实现其他注入策略,如字段注入。


接口源码

我们看一下接口源码与方法说明。如下所示接口的四个方法均有默认实现。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
  @Nullable
  default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    return null;
  }
  default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    return true;
  }
  @Nullable
  default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
      throws BeansException {
    return null;
  }
  @Deprecated
  @Nullable
  default PropertyValues postProcessPropertyValues(
      PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
    return pvs;
  }
}


postProcessBeforeInstantiation

在目标bean开始实例化前触发该方法。返回的bean对象可能是要使用的代理,而不是目标bean,从而有效地抑制了目标bean的默认实例化。如果此方法返回非null对象,则bean创建过程将被短路(也就是正常bean实例化的后续流程不再执行)。


此callback将应用于bean定义及其bean类,以及工厂方法定义,在这种情况下,返回的bean类型将在此处传递。后置处理器可以实现继承SmartInstantiationAwareBeanPostProcessor接口,以预测它们将在此处返回的bean对象的类型。


该方法将会返回要暴露的bean对象,而不是目标bean的默认实例,如果返回 null 继续默认实例化流程。


如下图所示,其在AbstractAutowireCapableBeanFactory的createBean方法创建Bean实例时被触发


4269bfd5ceeb44dcb1ab750a79d37928.png

//AbstractAutowireCapableBeanFactory
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  Object bean = null;
  if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    // Make sure bean class is actually resolved at this point.
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      Class<?> targetType = determineTargetType(beanName, mbd);
      if (targetType != null) {
        // 前置方法-尝试获取一个代理对象
        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
        if (bean != null) {
        // 后置方法 判断是否应该给bean设置属性还是跳过属性设置
          bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
        }
      }
    }
    mbd.beforeInstantiationResolved = (bean != null);
  }
  return bean;
}

4e4f10a213704d6aa29f415fddf2cf1d.png


应用实例


如AbstractAutoProxyCreator的postProcessBeforeInstantiation方法,将会尝试创建一个代理对象返回。如果这里返回的Bean不为null,那么将不会再执行Object beanInstance = doCreateBean(beanName, mbdToUse, args);方法。

f62d8e4484d8456c9147a0a681849caa.png


postProcessAfterInstantiation


在bean被实例化之后,通过构造函数或工厂方法,但在Spring属性填充(from explicit properties or autowiring)发生之前,执行操作。


这是在Spring的自动连接开始之前,在给定bean实例上执行自定义字段注入的理想回调。


当然返回结果为true时,说明应该为bean设置属性。如果返回结果为false,跳过bean属性赋值环节。


默认实现返回true。


a515b215483d4a4990a52aa956e6cbdb.png


postProcessProperties


在工厂将给定的属性值应用于给定的bean之前,对其进行后处理,而不需要任何属性描述符。


如果实现类提供自定义的{postProcessPropertyValues}实现,则应返回{ null}(默认值),否则返回{ pvs}。


在这个接口的未来版本中(删除了{postprocesspropertyvalue}),默认实现将直接返回给定的{ pvs}。


这个方法很重要哦,因为AutowiredAnnotationBeanPostProcessor就是InstantiationAwareBeanPostProcessor,其继承于InstantiationAwareBeanPostProcessorAdapter。在Bean实例化过程中,会在populateBean触发该方法的回调,其将会解析依赖(如 @Autowired SysFileService fileService;)。



7b9ce12337534d53a9cb40875252358b.png


以AutowiredAnnotationBeanPostProcessor为例,其postProcessProperties方法如下所示。可以看到其将会获取使用了@Autowired字段和方法,触发依赖的解析。

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
  InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
  try {
    metadata.inject(bean, beanName, pvs);
  }
  catch (BeanCreationException ex) {
    throw ex;
  }
  catch (Throwable ex) {
    throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
  }
  return pvs;
}


postProcessPropertyValues

与postProcessProperties方法不同的是,该方法多了参数属性描述符(PropertyDescriptor[])。在上图我们也可以看到,如果执行完postProcessProperties后pvsToUse仍旧为null,那么就会触发postProcessPropertyValues方法。


在DefaultListableBeanFactory将给定属性值应用于给定bean之前,对其进行后处理。允许检查是否满足了所有依赖项,例如基于bean属性设置器上的“Required”注解。


还允许替换要应用的属性值,通常是基于原始PropertyValues实例创建新的MutablePropertyValues 实例,添加或删除特定值。


默认返回PropertyValues pvs。

目录
相关文章
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
834 0
|
Java 开发者 Spring
灵活扩展Spring:后置处理器的实战技巧与最佳实践
灵活扩展Spring:后置处理器的实战技巧与最佳实践
267 0
|
Java 数据库连接 API
深入Spring原理-3.Bean的后置处理器
深入Spring原理-3.Bean的后置处理器
205 0
|
XML Java 程序员
spring-bean的生命周期和怎么配置spring-bean的后置处理器
spring-bean的生命周期和怎么配置spring-bean的后置处理器
255 0
|
安全 Java Spring
SpringBoot整合Spring Security,自定义登录成功/失败处理器,配置登录人数(三)
一般采用的是实现接口的方式:implements AuthenticationSuccessHandler 但是如果想要实现登录成功后跳转回登录前的页面可以直接继承SavedRequestAwareAuthenticationSuccessHandler这个类,该类的父类SimpleUrlAuthenticationSuccessHandler实现了AuthenticationSuccessHandler。
696 0
|
Java 开发者 Spring
Spring 中后置处理器的作用?
Spring 中后置处理器的作用?
383 0
|
SpringCloudAlibaba Java 中间件
Spring扩展点(一):后置处理器PostProcessor
`Spring`框架中大致提供了以下三个核心后置处理器:**`BeanDefinitionRegistryPostProcessor`,`BeanFactoryPostProcessor`,`BeanPostProcessor`**,其他的后置处理器都是继承自这三个
418 0
|
XML 缓存 Java
Spring Bean管理核心组件——后置处理器详解
Spring Bean管理核心组件——后置处理器详解
|
10月前
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
1360 0
|
11月前
|
人工智能 Java 测试技术
Spring Boot 集成 JUnit 单元测试
本文介绍了在Spring Boot中使用JUnit 5进行单元测试的常用方法与技巧,包括添加依赖、编写测试类、使用@SpringBootTest参数、自动装配测试模块(如JSON、MVC、WebFlux、JDBC等),以及@MockBean和@SpyBean的应用。内容实用,适合Java开发者参考学习。
1205 0