三个问题,一个答案
@Autowired 怎么把值塞进你的私有字段的?@PostConstruct 谁调的?AOP 代理谁造的?三个问题同一个答案:BeanPostProcessor(后置处理器)。它埋伏在 Bean 生命周期的每个关卡上动手脚,Spring 的「自动魔法」几乎全是它的作品。理解它,才算打开 Spring 的引擎盖。
两个基础关卡 + 一个全家桶
基础接口两道关:postProcessBeforeInitialization(初始化前)、postProcessAfterInitialization(初始化后,AOP 代理就在这一关生成)。真正干活多的是扩展接口 InstantiationAwareBeanPostProcessor:再加实例化前后、属性填充(postProcessProperties)三个钩子——@Autowired 的注入就发生在属性填充阶段。时机口诀:实例化 → 属性 → 初始化,每一站都有后置处理器。
内置四大金刚
容器启动时自动注册一批内置 BBP,认识四个最重要的:AutowiredAnnotationBeanPostProcessor——解析 @Autowired/@Value 完成注入;CommonAnnotationBeanPostProcessor——管 @PostConstruct/@PreDestroy/@Resource;AbstractAutoProxyCreator——扫描切面、生成 AOP 代理;ApplicationContextAwareProcessor——给实现 Aware 接口的 Bean 塞容器引用。你常用的注解,全是它们在幕后翻译。
亲手写一个
需求:所有实现了 Audit 接口的 Bean 就位时输出一行日志,三十行内搞定:
@Component
public class AuditPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof Audit) {
System.out.println("审计组件已就位:" + beanName);
}
return bean; // 原样返回;也可以返回包装后的代理对象
}
}两条纪律:返回值可以是新对象——AOP 代理的生成用的正是这个口子;BBP 自己也是 Bean,注册得越早话语权越大,用 @Order 或实现 PriorityOrdered 控制优先级——事务切面必须先于代理生成器被发现,就是靠这个顺序保障的。
与 BeanFactoryPostProcessor 的分工
另一个扩展接口 BeanFactoryPostProcessor 干的是另一段活:它作用于 BeanDefinition(图纸)——Bean 还没造的时候改定义:改 scope、改 class、批量注册新定义。分工口诀:BFPP 改图纸,BBP 改成品。MyBatis 的 Mapper 扫描注册、@Configuration 类的 CGLIB 增强,都在图纸阶段动手;扩展点全家福第 17 篇汇总。
下一篇讲一个面试容易翻车的混淆点:BeanFactory 与 FactoryBean——一个字母之差,一个是工厂本体,一个是工厂产品。
评论 (0)