BeanPostProcessor
1、概述
BeanPostProcessor:提供两个在 Spring 创建 Bean 的生命周期中的执行特定代码的方法。
方法 | 说明 |
---|---|
postProcessBeforeInitialization(Object bean, String beanName) | 在 Bean 初始化前调用,允许返回一个包装后的 Bean 实例。 |
postProcessAfterInitialization(Object bean, String beanName) | 在 Bean 初始化后调用,允许返回一个包装后的 Bean 实例。 |
1.1 相关接口
1)InstantiationAwareBeanPostProcessor
2)SmartInstantiationAwareBeanPostProcessor
3)MergedBeanDefinitionPostProcessor
4)DestructionAwareBeanPostProcessor
1.2 BeanPostProcessor 执行时机
在 Spring 框架中,BeanPostProcessor
的注册发生在 AbstractApplicationContext
中 refresh()
-> registerBeanPostProcessors()
,方法内会查找所有的 BeanPostProcessor
的 Bean,并按照优先级排序后注册到 BeanFactory 中。
2、应用
2.1 AOP
AOP 就是通过 BeanPostProcessor 接口的实现类来创建代理对象,并在调用目标方法前后插入切面逻辑。
- 初始化:Spring 容器启动时,会自动检测并注册所有实现 BeanPostProcessor 的 Bean。
- 实例化后处理:当一个 Bean 实例化后,Spring 会调用所有注册的
BeanPostProcessor
的postProcessAfterInitialization()
。 - 匹配切点表达式:
AnnotationAwareAspectJAutoProxyCreator
检查当前 Bean 是否匹配任何的切点表达式。 - 代理创建:如果匹配切点表达式,
AnnotationAwareAspectJAutoProxyCreator
会为该 Bean 创建代理对象,插入具体逻辑。 - 代理替换:通过
AnnotationAwareAspectJAutoProxyCreator
的postProcessAfterInitialization()
返回代理对象来替代原始 Bean。
AOP 相关方法调用:
初始化阶段:
AbstractAutoProxyCreator.setBeanFactory()
:设置 BeanFactory,用于后续获取 BeanDefinition 和对应依赖。AbstractAutoProxyCreator.initBeanFactory()
:初始化一些必要的 BeanPostProcessor。AbstractAutoProxyCreator.postProcessBeforeInitialization()
:在 Bean 初始化前,检查是否需要为该 Bean 创建代理。
创建代理:
AbstractAutoProxyCreator.determineTargetClass()
:确定目标 Bean 的类信息,判断是否需要代理。AbstractAutoProxyCreator.shouldSkip()
:判断是否需要跳过代理的创建,如已经代理过的 Bean。AbstractAutoProxyCreator.createProxy()
:实际创建代理的入口,根据配置选择 JDK/CGLIB。
AspectJ 处理:
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()
:扫描并找出所有可用的切面(Aspect)和通知(Advice),包括那些标记了@Aspect
的类和它们的方法。AspectJAdvisorFactory.getAdvisors()
:使用AspectJAdvisorFactory
来创建切面的Advisor。
代理工厂的使用:
AbstractAutoProxyCreator.createAopProxy()
:根据配置决定使用哪种代理工厂(默认DefaultAopProxyFactory
)来创建代理。DefaultAopProxyFactory.createAopProxy()
:在该工厂中,根据配置的代理类型(JDK或CGLIB)创建具体的代理实例。
最终代理生成:
- JDK:
JdkDynamicAopProxy.getProxy()
- CGLIB:
ObjenesisCglibAopProxy.createProxyClass()
和Cglib2AopProxy.getProxy()
2.2 @Autowired
Spring 中处理 @Autowired 是通过 AutowiredAnnotationBeanPostProcessor
实现的。
- 初始化:Spring 容器启动时,会自动检测并注册所有实现 BeanPostProcessor 的 Bean。
- 实例化后处理:当一个 Bean 实例化后,Spring 会调用所有注册的
BeanPostProcessor
的postProcessAfterInitialization()
。 - 查找 @Autowired:在
AutowiredAnnotationBeanPostProcessor
的postProcessProperties()
中,会检查目标 Bean 的字段和方法上是否存在 @Autowired。 - 解析依赖:对于每个标记 @Autowired 的字段或方法,都会尝试从 Spring 容器中找到合适的 Bean。
- 依赖注入:找到匹配的 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
实现的。
- 初始化:Spring 容器启动时,会自动检测并注册所有实现 BeanPostProcessor 的 Bean。
- 查找
@PostConstruct
:在 Bean 实例化并设置完属性值后,Spring 会调用CommonAnnotationBeanPostProcessor
的postProcessAfterInitialization()
,在此方法中,会扫描@PostConstruct
修饰的方法。 - 执行
@PostConstruct
:CommonAnnotationBeanPostProcessor
会按照顺序执行扫描到的@PostConstruct
方法。 - 完成初始化:执行完
@PostConstruct
方法后,CommonAnnotationBeanPostProcessor
会返回经过处理过的 Bean 实例,并认为 Bean 已完成初始化,可以正常使用。
3、总结
BeanPostProcessor 是 Spring 中非常重要的扩展接口,Spring 通过 BeanPostProcessor 实现了很多常用的功能,如:
转载自:https://juejin.cn/post/7392070976093356095