likes
comments
collection
share

BeanPostProcessor

作者站长头像
站长
· 阅读数 17

1、概述

BeanPostProcessor:提供两个在 Spring 创建 Bean 的生命周期中的执行特定代码的方法。

方法说明
postProcessBeforeInitialization(Object bean, String beanName)在 Bean 初始化前调用,允许返回一个包装后的 Bean 实例。
postProcessAfterInitialization(Object bean, String beanName)在 Bean 初始化后调用,允许返回一个包装后的 Bean 实例。

1.1 相关接口

BeanPostProcessor 1)InstantiationAwareBeanPostProcessor

BeanPostProcessor

2)SmartInstantiationAwareBeanPostProcessor

BeanPostProcessor

3)MergedBeanDefinitionPostProcessor

BeanPostProcessor

4)DestructionAwareBeanPostProcessor

BeanPostProcessor

1.2 BeanPostProcessor 执行时机

在 Spring 框架中,BeanPostProcessor 的注册发生在 AbstractApplicationContextrefresh() -> registerBeanPostProcessors(),方法内会查找所有的 BeanPostProcessor 的 Bean,并按照优先级排序后注册到 BeanFactory 中。 BeanPostProcessor

2、应用

2.1 AOP

AOP 就是通过 BeanPostProcessor 接口的实现类来创建代理对象,并在调用目标方法前后插入切面逻辑。

  1. 初始化:Spring 容器启动时,会自动检测并注册所有实现 BeanPostProcessor 的 Bean。
  2. 实例化后处理:当一个 Bean 实例化后,Spring 会调用所有注册的 BeanPostProcessorpostProcessAfterInitialization()
  3. 匹配切点表达式AnnotationAwareAspectJAutoProxyCreator 检查当前 Bean 是否匹配任何的切点表达式。
  4. 代理创建:如果匹配切点表达式,AnnotationAwareAspectJAutoProxyCreator 会为该 Bean 创建代理对象,插入具体逻辑。
  5. 代理替换:通过AnnotationAwareAspectJAutoProxyCreatorpostProcessAfterInitialization() 返回代理对象来替代原始 Bean。

BeanPostProcessor

AOP 相关方法调用:

初始化阶段

  1. AbstractAutoProxyCreator.setBeanFactory():设置 BeanFactory,用于后续获取 BeanDefinition 和对应依赖。
  2. AbstractAutoProxyCreator.initBeanFactory():初始化一些必要的 BeanPostProcessor。
  3. AbstractAutoProxyCreator.postProcessBeforeInitialization():在 Bean 初始化前,检查是否需要为该 Bean 创建代理。

创建代理

  1. AbstractAutoProxyCreator.determineTargetClass():确定目标 Bean 的类信息,判断是否需要代理。
  2. AbstractAutoProxyCreator.shouldSkip():判断是否需要跳过代理的创建,如已经代理过的 Bean。
  3. AbstractAutoProxyCreator.createProxy():实际创建代理的入口,根据配置选择 JDK/CGLIB。

AspectJ 处理

  1. AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors():扫描并找出所有可用的切面(Aspect)和通知(Advice),包括那些标记了@Aspect的类和它们的方法。
  2. AspectJAdvisorFactory.getAdvisors():使用AspectJAdvisorFactory来创建切面的Advisor。

代理工厂的使用

  1. AbstractAutoProxyCreator.createAopProxy():根据配置决定使用哪种代理工厂(默认DefaultAopProxyFactory)来创建代理。
  2. DefaultAopProxyFactory.createAopProxy():在该工厂中,根据配置的代理类型(JDK或CGLIB)创建具体的代理实例。

最终代理生成

  1. JDK:JdkDynamicAopProxy.getProxy()
  2. CGLIB:ObjenesisCglibAopProxy.createProxyClass()Cglib2AopProxy.getProxy()

2.2 @Autowired

Spring 中处理 @Autowired 是通过 AutowiredAnnotationBeanPostProcessor 实现的。

  1. 初始化:Spring 容器启动时,会自动检测并注册所有实现 BeanPostProcessor 的 Bean。
  2. 实例化后处理:当一个 Bean 实例化后,Spring 会调用所有注册的 BeanPostProcessorpostProcessAfterInitialization()
  3. 查找 @Autowired:在 AutowiredAnnotationBeanPostProcessorpostProcessProperties() 中,会检查目标 Bean 的字段和方法上是否存在 @Autowired。
  4. 解析依赖:对于每个标记 @Autowired 的字段或方法,都会尝试从 Spring 容器中找到合适的 Bean。
  5. 依赖注入:找到匹配的 Bean 后,会执行依赖注入。对于字段,会直接设置字段值,对于构造函数,会调用相应的构造函数/setter 方法注入依赖。

postProcessProperties() 相关代码:

/**
  * pvs:包含 Bean 属性值的集合。
  * bean:正在处理的 Bean 实例。
  * beanName:Bean 的名称。
  */
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    // 1. 查找正在处理的 Bean 的自动装配信息,即哪些字段/方法需要被自动注入
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    try {
        // 2. 执行依赖注入
        metadata.inject(bean, beanName, pvs);
    }
    catch (BeanCreationException ex) {
        throw ex;
    }
    catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
    }
    // 3. 返回处理过的 PropertyValues 对象
    return pvs;
}

2.3 @PostConstruct

Spring 中 @PostConstruct@PreDestory 是通过 CommonAnnotationBeanPostProcessor 实现的。

  1. 初始化:Spring 容器启动时,会自动检测并注册所有实现 BeanPostProcessor 的 Bean。
  2. 查找 @PostConstruct:在 Bean 实例化并设置完属性值后,Spring 会调用 CommonAnnotationBeanPostProcessorpostProcessAfterInitialization(),在此方法中,会扫描 @PostConstruct 修饰的方法。
  3. 执行 @PostConstructCommonAnnotationBeanPostProcessor 会按照顺序执行扫描到的 @PostConstruct 方法。
  4. 完成初始化:执行完 @PostConstruct 方法后,CommonAnnotationBeanPostProcessor 会返回经过处理过的 Bean 实例,并认为 Bean 已完成初始化,可以正常使用。

3、总结

BeanPostProcessor 是 Spring 中非常重要的扩展接口,Spring 通过 BeanPostProcessor 实现了很多常用的功能,如:

BeanPostProcessor

转载自:https://juejin.cn/post/7392070976093356095
评论
请登录