Spring Framework源码解析——BeanFactoryAware
版权声明
- 本文原创作者:谷哥的小弟
- 作者博客地址:http://blog.csdn.net/lfdfhl
一、概述
BeanFactoryAware
是 Spring 框架中用于让 Bean 在初始化阶段感知并获取其所属 BeanFactory
容器引用的核心回调接口。通过实现该接口,Bean 可以在运行时直接访问底层的 BeanFactory
,从而具备动态获取其他 Bean、查询 Bean 定义、检查 Bean 状态等能力。
作为 Spring Aware 系列接口(如 ApplicationContextAware
、BeanNameAware
等)的重要成员,BeanFactoryAware
体现了 Spring 容器“按需暴露内部能力”的设计原则:在保持控制反转(IoC)主干的同时,为高级用户提供必要的底层访问通道。
二、接口定义
public interface BeanFactoryAware extends Aware {/*** 在 Bean 初始化早期阶段由容器调用* 注入当前 Bean 所属的 BeanFactory 实例* @param beanFactory 当前使用的 BeanFactory* @throws BeansException 如果设置失败*/void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
- 继承自
Aware
标记接口:表明该接口用于“感知”容器能力; - 回调方法
setBeanFactory()
:由容器自动调用,注入BeanFactory
引用; - 执行时机早:在属性注入完成后、
BeanPostProcessor
初始化回调之前; - 适用场景:需要直接操作
BeanFactory
API 的高级用例,如动态 Bean 创建、作用域检查、类型推断等。
三、核心执行流程分析
BeanFactoryAware
的调用发生在 AbstractAutowireCapableBeanFactory.initializeBean()
方法的早期阶段,具体由 invokeAwareMethods()
方法处理。
3.1 initializeBean()
方法(入口)
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {// 1. 调用 Aware 接口方法(包括 BeanFactoryAware)invokeAwareMethods(beanName, bean);Object wrappedBean = bean;// 2. 执行 BeanPostProcessor 的 postProcessBeforeInitializationif (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}// 3. 调用 InitializingBean.afterPropertiesSet() 和 init-methodinvokeInitMethods(beanName, wrappedBean, mbd);// 4. 执行 BeanPostProcessor 的 postProcessAfterInitializationif (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}
3.2 invokeAwareMethods()
方法源码
private void invokeAwareMethods(String beanName, Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}if (bean instanceof BeanFactoryAware) {// 关键:将当前 BeanFactory 注入((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}// 注意:ApplicationContextAware 不在此处处理(由 ApplicationContextAwareProcessor 处理)}
}
- 类型检查:通过
instanceof
判断是否实现BeanFactoryAware
; - 注入对象:直接传入
this
,即当前AbstractAutowireCapableBeanFactory
实例; - 执行顺序:在
BeanNameAware
和BeanClassLoaderAware
之后,但在ApplicationContextAware
(由BeanPostProcessor
处理)之前; - 无空值检查:
BeanFactory
必然存在,无需判空。
关键点:与
ApplicationContextAware
不同,BeanFactoryAware
的注入直接由BeanFactory
自身完成,不依赖BeanPostProcessor
。
四、执行时机与生命周期位置
BeanFactoryAware.setBeanFactory()
的执行顺序如下:
- Bean 实例化(
createBeanInstance
) - 属性注入(
populateBean
) invokeAwareMethods()
→setBeanFactory()
ApplicationContextAwareProcessor.postProcessBeforeInitialization()
(注入ApplicationContext
等)@PostConstruct
方法InitializingBean.afterPropertiesSet()
init-method
结论:
BeanFactoryAware
是最早可获取容器引用的回调之一,此时ApplicationContext
尚未注入(若存在)。
五、典型应用场景
5.1 动态获取原型(Prototype)Bean
@Component
public class PrototypeBeanFactory implements BeanFactoryAware {private BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) {this.beanFactory = beanFactory;}public MyPrototypeService createNewInstance() {// 每次调用都返回新的 Prototype Bean 实例return beanFactory.getBean(MyPrototypeService.class);}
}
优势:避免将 Prototype Bean 直接注入 Singleton Bean 导致的“单例化”问题。
5.2 检查 Bean 是否存在或类型兼容
@Component
public class ConditionalService implements BeanFactoryAware {private ConfigurableListableBeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) {// 通常可安全转型为 ConfigurableListableBeanFactorythis.beanFactory = (ConfigurableListableBeanFactory) beanFactory;}public boolean isBeanOfType(String beanName, Class<?> type) {if (!beanFactory.containsBean(beanName)) {return false;}Class<?> beanType = beanFactory.getType(beanName);return type.isAssignableFrom(beanType);}
}
5.3 获取 Bean 定义元数据
public void inspectBeanDefinition(String beanName) {if (beanFactory instanceof ConfigurableListableBeanFactory) {BeanDefinition bd = ((ConfigurableListableBeanFactory) beanFactory).getBeanDefinition(beanName);System.out.println("Scope: " + bd.getScope());System.out.println("Lazy Init: " + bd.isLazyInit());}
}
六、与 ApplicationContextAware
和 @Autowired BeanFactory
的对比
方式 | 类型 | 注入对象 | 执行时机 | 是否依赖 Spring API | 推荐度 |
---|---|---|---|---|---|
BeanFactoryAware | 接口回调 | BeanFactory | 属性注入后、BeanPostProcessor 前 | 是 | ⭐⭐ |
ApplicationContextAware | 接口回调 | ApplicationContext | BeanPostProcessor 阶段 | 是 | ⭐⭐ |
@Autowired BeanFactory | 依赖注入 | BeanFactory | 属性注入阶段 | 是(但更简洁) | ⭐⭐⭐⭐ |
关键区别:
BeanFactory
是底层容器,功能较基础;ApplicationContext
是高级容器,提供事件、国际化、资源加载等能力;@Autowired BeanFactory
更简洁,且执行时机略早(在populateBean
阶段完成)。
@Service
public class MyService {@Autowiredprivate BeanFactory beanFactory; // 自动注入当前 BeanFactory
}
注意:Spring 会自动将
BeanFactory
作为可注入的依赖,无需额外配置。
七、源码设计思想分析
BeanFactoryAware
的设计体现了 Spring 的以下核心思想:
7.1 分层架构
BeanFactory
:提供最基础的 IoC 容器能力(Bean 创建、依赖注入);ApplicationContext
:在BeanFactory
基础上扩展企业级功能;BeanFactoryAware
允许用户直接访问底层,满足高性能或定制化需求。
7.2 回调机制的精细化控制
- 不同
Aware
接口在不同阶段注入,确保依赖可用性; BeanFactoryAware
由BeanFactory
自身处理,保证其在任何容器(包括非ApplicationContext
)中均可工作。
7.3 向后兼容与扩展性
- 保留接口方式以支持传统应用;
- 同时支持现代依赖注入方式(
@Autowired
),兼顾简洁性与灵活性。
八、最佳实践与注意事项
8.1 注意事项
- 避免滥用:不应将
BeanFactory
作为全局服务分发器; - 类型安全:
BeanFactory
接口功能有限,如需高级操作(如获取BeanDefinition
),需转型为ConfigurableListableBeanFactory
; - 作用域问题:在 Prototype Bean 中持有
BeanFactory
引用是安全的; - 测试复杂度:实现
BeanFactoryAware
会增加单元测试难度(需模拟BeanFactory
)。
8.2 替代方案建议
- 优先使用
@Autowired BeanFactory
:代码更简洁,语义更清晰; - 如需高级功能,注入
ApplicationContext
:它继承自BeanFactory
,功能更全; - 避免在业务逻辑中直接依赖容器:应通过接口或服务抽象解耦。
九、总结
BeanFactoryAware
是 Spring 框架中用于让 Bean 获取底层 BeanFactory
引用的重要接口。其核心方法 setBeanFactory()
由 AbstractAutowireCapableBeanFactory
在初始化早期直接调用,执行时机早于 BeanPostProcessor
和 ApplicationContextAware
。
尽管功能强大,但出于代码简洁性和现代编程风格考虑,推荐优先使用 @Autowired BeanFactory
。理解 BeanFactoryAware
的执行机制、生命周期位置及其与 ApplicationContext
的关系,有助于深入掌握 Spring 容器的分层架构与扩展能力。
setBeanFactory()
由BeanFactory
自身调用,不依赖BeanPostProcessor
;- 执行时机:属性注入后、
BeanPostProcessor
前; - 注入的是
BeanFactory
实例(通常是DefaultListableBeanFactory
); - 适用于动态获取 Prototype Bean、检查 Bean 状态等场景;
- 现代 Spring 应用更推荐使用
@Autowired BeanFactory
。