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。

目录
相关文章
|
3月前
|
监控 安全 Java
【开发者必备】Spring Boot中自定义注解与处理器的神奇魔力:一键解锁代码新高度!
【8月更文挑战第29天】本文介绍如何在Spring Boot中利用自定义注解与处理器增强应用功能。通过定义如`@CustomProcessor`注解并结合`BeanPostProcessor`实现特定逻辑处理,如业务逻辑封装、配置管理及元数据分析等,从而提升代码整洁度与可维护性。文章详细展示了从注解定义、处理器编写到实际应用的具体步骤,并提供了实战案例,帮助开发者更好地理解和运用这一强大特性,以实现代码的高效组织与优化。
163 0
|
6月前
|
Java 开发者 Spring
灵活扩展Spring:后置处理器的实战技巧与最佳实践
灵活扩展Spring:后置处理器的实战技巧与最佳实践
76 0
|
6月前
|
Java 数据库连接 API
深入Spring原理-3.Bean的后置处理器
深入Spring原理-3.Bean的后置处理器
62 0
|
6月前
|
XML Java 程序员
spring-bean的生命周期和怎么配置spring-bean的后置处理器
spring-bean的生命周期和怎么配置spring-bean的后置处理器
80 0
|
安全 Java Spring
SpringBoot整合Spring Security,自定义登录成功/失败处理器,配置登录人数(三)
一般采用的是实现接口的方式:implements AuthenticationSuccessHandler 但是如果想要实现登录成功后跳转回登录前的页面可以直接继承SavedRequestAwareAuthenticationSuccessHandler这个类,该类的父类SimpleUrlAuthenticationSuccessHandler实现了AuthenticationSuccessHandler。
311 0
|
Java 开发者 Spring
Spring 中后置处理器的作用?
Spring 中后置处理器的作用?
201 0
|
SpringCloudAlibaba Java 中间件
Spring扩展点(一):后置处理器PostProcessor
`Spring`框架中大致提供了以下三个核心后置处理器:**`BeanDefinitionRegistryPostProcessor`,`BeanFactoryPostProcessor`,`BeanPostProcessor`**,其他的后置处理器都是继承自这三个
152 0
|
XML 缓存 Java
Spring Bean管理核心组件——后置处理器详解
Spring Bean管理核心组件——后置处理器详解
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
1月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
161 2