spring 一
你说的应该是 BeanPostProcessor,它是 Spring 中非常重要的一个扩展点,也是 Spring AOP、@Autowired、@Resource 等功能的基础。
很多面试都会问:
BeanPostProcessor 有什么作用?
一句话概括:
BeanPostProcessor 用于在 Spring Bean 初始化前后,对 Bean 进行增强、修改或替换。
一、Bean 的完整生命周期
一个 Bean 从创建到放入 IOC 容器,大致经历下面几个步骤:
实例化 Bean
│
▼
属性注入(@Autowired)
│
▼
Aware 回调
│
▼
BeanPostProcessor#postProcessBeforeInitialization()
│
▼
初始化
(@PostConstruct、afterPropertiesSet、init-method)
│
▼
BeanPostProcessor#postProcessAfterInitialization()
│
▼
放入 IOC 容器
BeanPostProcessor 正好位于初始化的前后。
二、BeanPostProcessor 有两个方法
接口定义非常简单:
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName);
Object postProcessAfterInitialization(Object bean, String beanName);
}
1、初始化前
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
System.out.println(beanName + " 初始化前");
return bean;
}
执行时机:
实例化
↓
属性注入
↓
BeforeInitialization
↓
@PostConstruct
2、初始化后
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println(beanName + " 初始化后");
return bean;
}
执行时机:
@PostConstruct
↓
AfterInitialization
↓
Bean 放入 IOC
三、为什么要有它?
因为 Spring 希望:
允许开发者在 Bean 创建过程中做统一增强。
例如:
有 1000 个 Bean。
如果想:
打印日志
或者:
生成代理
不用每个 Bean 都修改。
只需要:
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
}
Spring 创建每一个 Bean 时都会经过这里。
四、Spring 哪些功能依赖 BeanPostProcessor?
这也是面试最喜欢问的。
① AOP
例如:
@Transactional
为什么:
userService
最后变成了:
UserService$$SpringCGLIB$$xxx
原因就是:
postProcessAfterInitialization()
里面:
判断:
有没有 AOP
↓
创建代理对象
↓
返回代理对象
所以:
IOC 容器里最终放的是:
代理对象
而不是:
原对象
② @Autowired
很多人以为:
@Autowired
是在 BeanPostProcessor。
实际上:
准确来说:
它是:
InstantiationAwareBeanPostProcessor
这是:
BeanPostProcessor 的子接口。
负责:
扫描字段
↓
找到 Bean
↓
反射赋值
例如:
@Autowired
private UserService userService;
就是:
AutowiredAnnotationBeanPostProcessor
完成注入。
③ @Resource
也是:
CommonAnnotationBeanPostProcessor
实现。
④ @PostConstruct
也是:
CommonAnnotationBeanPostProcessor
处理。
它负责:
找到
@PostConstruct
↓
调用方法
⑤ @Async
例如:
@Async
public void sendEmail(){}
最终:
也是:
BeanPostProcessor
生成代理。
⑥ @Transactional
也是:
InfrastructureAdvisorAutoProxyCreator
它本身就是:
BeanPostProcessor。
负责:
创建事务代理
五、BeanPostProcessor 能做什么?
例如:
修改 Bean
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if(bean instanceof UserService){
((UserService) bean).setName("张三");
}
return bean;
}
替换 Bean
例如:
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if(bean instanceof UserService){
return new UserServiceProxy(bean);
}
return bean;
}
Spring:
以后获取:
applicationContext.getBean(UserService.class);
得到的是:
UserServiceProxy
而不是:
UserService
打印日志
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
System.out.println(beanName);
return bean;
}
所有 Bean 都会打印。
六、BeanPostProcessor 和 BeanFactoryPostProcessor 区别
很多人容易混。
| 对比 | BeanPostProcessor | BeanFactoryPostProcessor |
|---|---|---|
| 操作对象 | Bean 实例 | BeanDefinition |
| 执行时间 | Bean 创建过程中 | Bean 创建之前 |
| 是否有 Bean | 已经实例化 | 还没有实例化 |
| 作用 | 增强 Bean、生成代理 | 修改 BeanDefinition |
例如:
BeanDefinition:
class=com.demo.UserService
scope=singleton
lazy=false
BeanFactoryPostProcessor:
可以改:
scope=prototype
但是:
Bean:
还没创建。
七、源码流程
Spring 创建 Bean:
AbstractAutowireCapableBeanFactory
↓
createBean()
↓
doCreateBean()
↓
populateBean()
│
├── @Autowired
│
▼
initializeBean()
│
├── postProcessBeforeInitialization()
│
├── @PostConstruct
│
├── afterPropertiesSet()
│
└── postProcessAfterInitialization()
│
▼
AOP代理
八、面试回答(推荐)
BeanPostProcessor 是 Spring 提供的一个 Bean 后置处理器,也是 Spring 最重要的扩展点之一。它允许开发者在 Bean 初始化前后对 Bean 进行增强、修改甚至替换。接口中主要有两个方法:
postProcessBeforeInitialization()和postProcessAfterInitialization(),分别在初始化方法执行前后调用。Spring 中很多核心功能都是基于 BeanPostProcessor 实现的,例如 AOP 代理、@Autowired、@Resource、@PostConstruct、@Async、@Transactional等。特别是 AOP,会在postProcessAfterInitialization()中判断 Bean 是否需要代理,如果需要则返回代理对象,因此最终放入 IOC 容器中的往往不是原始对象,而是代理对象。这也是 Spring 能够实现无侵入式功能增强的核心机
浙公网安备 33010602011771号