一、三大扩展点概览

扩展点作用时机作用对象典型用途
BeanFactoryPostProcessor容器启动初期,在 Bean 实例化之前Bean 的定义元数据(BeanDefinition)修改配置元数据,比如替换占位符 ${}、动态修改类名等
BeanPostProcessorBean 实例化之后,初始化前后Bean 的实例对象本身增强 Bean(如 AOP 代理)、打印日志、校验等
FactoryBeanBean 实例化过程中自定义复杂对象的创建逻辑创建非标准对象(如 MyBatis 的 Mapper 接口代理)

二、逐个深入理解

1. BeanPostProcessor增强 Bean 实例

✅ 核心思想:

在 Spring 创建完一个 Bean 实例后,但在调用其初始化方法(如 @PostConstructInitializingBean.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() 这个动作。


四、对比总结

维度BeanFactoryPostProcessorBeanPostProcessorFactoryBean
作用时机Bean 实例化之前Bean 初始化前后Bean 实例化过程中
操作对象BeanDefinition(元数据)Bean 实例对象创建 Bean 的逻辑
是否自动注册是(但返回的是 getObject() 结果)
是否被代理(自身是代理者)可以被代理
典型用途替换 ${}、修改类名AOP、日志、注解处理创建代理、Mapper、复杂对象
获取方式正常 getBean正常 getBean& 前缀获取自身

五、如何记忆?

  • BeanFactoryPostProcessor → “改配置
    → 工厂还没开工,先改图纸(BeanDefinition)

  • BeanPostProcessor → “加工成品
    → 产品(Bean)造好了,但出厂前再加工一下(加 logo、包装)

  • FactoryBean → “代工厂
    → 我不直接生产,我让代工厂帮我生产(复杂对象)


六、实际开发中的使用建议

  1. 优先使用注解和自动配置,而不是手动写这些扩展点。
  2. BeanPostProcessor 很强大,但慎用,避免影响性能或破坏生命周期。
  3. FactoryBean 多用于框架集成,如 MyBatis、Feign、Dubbo 等。
  4. BeanFactoryPostProcessor 适合做全局配置处理,如加密配置解密、环境切换等。

七、总结

这三大扩展点是 Spring 高度可扩展性的核心体现:

  • BeanFactoryPostProcessor 让你在容器启动时修改配置
  • BeanPostProcessor 让你在 Bean 创建时增强行为
  • FactoryBean 让你自定义对象的创建方式

掌握它们,你就掌握了 Spring 容器的“上帝模式”,能够深入理解 Spring 是如何实现 AOP、事务、自动装配等高级功能的。

💡 提示:Spring Boot 的自动配置、条件化装配、@ConfigurationProperties 等功能,底层都依赖于这些扩展机制。


如果你正在学习 Spring 源码,建议从 BeanPostProcessor 入手,它是理解 Spring AOP 和 Bean 生命周期的关键入口。

更多推荐