Spring容器三大扩展点深度解析
一、三大扩展点概览
| 扩展点 | 作用时机 | 作用对象 | 典型用途 |
|---|---|---|---|
BeanFactoryPostProcessor | 容器启动初期,在 Bean 实例化之前 | Bean 的定义元数据(BeanDefinition) | 修改配置元数据,比如替换占位符 ${}、动态修改类名等 |
BeanPostProcessor | Bean 实例化之后,初始化前后 | Bean 的实例对象本身 | 增强 Bean(如 AOP 代理)、打印日志、校验等 |
FactoryBean | Bean 实例化过程中 | 自定义复杂对象的创建逻辑 | 创建非标准对象(如 MyBatis 的 Mapper 接口代理) |
二、逐个深入理解
1. BeanPostProcessor:增强 Bean 实例
✅ 核心思想:
在 Spring 创建完一个 Bean 实例后,但在调用其初始化方法(如 @PostConstruct、InitializingBean.afterPropertiesSet())前后,允许你插入自定义逻辑。
✅ 回调方法:
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName);
Object postProcessAfterInitialization(Object bean, String beanName);
}
before:在初始化方法执行前调用(如@PostConstruct前)after:在初始化方法执行后调用(如@PostConstruct后)
📌 注意:它操作的是 已经实例化但尚未完全初始化的 Bean 对象。
✅ 使用场景:
- AOP 自动代理:Spring AOP 的底层就是通过
BeanPostProcessor实现的(如AbstractAutoProxyCreator)。 - 日志打印:如你例子中的
InstantiationTracingBeanPostProcessor,打印每个 Bean 的创建信息。 - 自动注入增强:如
AutowiredAnnotationBeanPostProcessor,处理@Autowired、@Value等注解。 - Bean 包装:返回一个代理对象(如事务代理、缓存代理)。
✅ 特殊规则:
- 自动注册:只要你在 Spring 容器中定义了一个
BeanPostProcessor类型的 Bean,Spring 会自动识别并注册它。 - 提前加载:所有
BeanPostProcessor会在其他普通 Bean 创建前被实例化,因为它们要参与其他 Bean 的创建过程。 - 不参与代理:由于
BeanPostProcessor本身是“增强器”,所以它不会被 AOP 代理(否则会无限递归)。
2. BeanFactoryPostProcessor:修改 Bean 的定义(元数据)
✅ 核心思想:
在 Spring 容器加载了所有的 Bean 定义(XML 或注解),但还没有创建任何 Bean 实例之前,允许你修改这些 Bean 的“蓝图”(即 BeanDefinition)。
✅ 典型实现:
PropertySourcesPlaceholderConfigurer:把${jdbc.url}这样的占位符替换成真实值。PropertyOverrideConfigurer:用外部.properties文件覆盖 Bean 的属性值。
✅ 使用场景:
- 外部化配置:从
jdbc.properties文件读取数据库连接信息,替换 XML 中的${}。 - 动态修改类名:比如根据环境切换实现类:
配置文件中设置<bean id="service" class="${service.impl.class}"/>service.impl.class=com.example.RealServiceImpl。 - 注册自定义类型转换器:比如添加
PropertyEditor。
✅ 重要区别:
- 它操作的是 BeanDefinition(元数据),不是 Bean 实例。
- 如果你在
BeanFactoryPostProcessor中手动调用getBean(),会导致该 Bean 提前实例化,破坏 Spring 生命周期,应避免。
✅ 注册方式:
和 BeanPostProcessor 一样,只要定义为 Bean,Spring 会自动识别并运行。
3. FactoryBean:自定义复杂对象的创建方式
✅ 核心思想:
有时候你想注册的不是一个普通类的实例,而是一个需要复杂逻辑创建的对象(比如 MyBatis 的 Mapper 接口、JDK 动态代理、第三方库对象等)。这时你可以实现 FactoryBean 接口,告诉 Spring:“让我来创建这个对象”。
✅ 接口方法:
public interface FactoryBean<T> {
T getObject() throws Exception; // 返回你要创建的对象
Class<?> getObjectType(); // 返回对象类型
boolean isSingleton(); // 是否单例(默认 true)
}
✅ 使用场景:
- MyBatis 的 Mapper 接口:接口本身不能 new,但 Spring 需要返回一个代理对象,这就是
MapperFactoryBean的作用。 - 创建代理对象:比如用
Proxy.newProxyInstance()创建 JDK 动态代理。 - 集成第三方库:如 JMS Connection、Redis Template 等需要复杂初始化的对象。
✅ 获取 FactoryBean 本身:
默认 getBean("myFactoryBean") 返回的是 getObject() 的结果。
如果你想获取 FactoryBean 实例本身,需要用:
context.getBean("&myFactoryBean");
(注意前面的 & 符号)
三、三者执行顺序(生命周期视角)
假设我们有一个 Bean userService,它的创建过程如下:
1. Spring 读取配置(XML/注解) → 生成 BeanDefinition
└── 此时,BeanFactoryPostProcessor 可以修改这个 BeanDefinition
(如替换 ${} 占位符,修改 class 名)
2. Spring 开始创建 userService 实例
├── 实例化(new UserService())
├── 填充属性(@Autowired 注入)
├── 调用 BeanPostProcessor.postProcessBeforeInitialization()
(如处理 @PostConstruct)
├── 初始化(InitializingBean.afterPropertiesSet())
├── 调用 BeanPostProcessor.postProcessAfterInitialization()
(如创建 AOP 代理)
└── Bean 创建完成,放入容器
📌
FactoryBean是在“实例化”阶段介入的,它替代了new UserService()这个动作。
四、对比总结
| 维度 | BeanFactoryPostProcessor | BeanPostProcessor | FactoryBean |
|---|---|---|---|
| 作用时机 | Bean 实例化之前 | Bean 初始化前后 | Bean 实例化过程中 |
| 操作对象 | BeanDefinition(元数据) | Bean 实例对象 | 创建 Bean 的逻辑 |
| 是否自动注册 | 是 | 是 | 是(但返回的是 getObject() 结果) |
| 是否被代理 | 是 | 否(自身是代理者) | 可以被代理 |
| 典型用途 | 替换 ${}、修改类名 | AOP、日志、注解处理 | 创建代理、Mapper、复杂对象 |
| 获取方式 | 正常 getBean | 正常 getBean | & 前缀获取自身 |
五、如何记忆?
-
BeanFactoryPostProcessor→ “改配置”
→ 工厂还没开工,先改图纸(BeanDefinition) -
BeanPostProcessor→ “加工成品”
→ 产品(Bean)造好了,但出厂前再加工一下(加 logo、包装) -
FactoryBean→ “代工厂”
→ 我不直接生产,我让代工厂帮我生产(复杂对象)
六、实际开发中的使用建议
- 优先使用注解和自动配置,而不是手动写这些扩展点。
BeanPostProcessor很强大,但慎用,避免影响性能或破坏生命周期。FactoryBean多用于框架集成,如 MyBatis、Feign、Dubbo 等。BeanFactoryPostProcessor适合做全局配置处理,如加密配置解密、环境切换等。
七、总结
这三大扩展点是 Spring 高度可扩展性的核心体现:
BeanFactoryPostProcessor让你在容器启动时修改配置;BeanPostProcessor让你在 Bean 创建时增强行为;FactoryBean让你自定义对象的创建方式。
掌握它们,你就掌握了 Spring 容器的“上帝模式”,能够深入理解 Spring 是如何实现 AOP、事务、自动装配等高级功能的。
💡 提示:Spring Boot 的自动配置、条件化装配、
@ConfigurationProperties等功能,底层都依赖于这些扩展机制。
如果你正在学习 Spring 源码,建议从 BeanPostProcessor 入手,它是理解 Spring AOP 和 Bean 生命周期的关键入口。
更多推荐


所有评论(0)