BeanFactory
接口BeanFactory
API为 Spring 的 IoC 功能提供了底层基础。它的特定契约主要用于与Spring 的其他部分和相关的第三方框架集成,它的 DefaultListableBeanFactory
实现是高级 GenericApplicationContext
容器中的关键委托。
BeanFactory
和相关接口 ( 如 BeanFactoryAware
、InitializingBean
、DisposableBean
) 是其他框架组件的重要集成点。通过不需要任何注释甚至反射,它们允许容器及其组件之间非常高效的交互。应用程序级Bean可以使用相同的回调接口,但通常更喜欢声明性依赖项注入,可以通过注释,也可以通过编程配置。
注意,核心的 BeanFactory
API级别及其 DefaultListableBeanFactory
实现没有对要使用的配置格式或任何组件注释做任何假设。所有这些样式都是通过扩展实现的 ( 比如 XmlBeanDefinitionReader
和 AutowiredAnnotationBeanPostProcessor
),并将共享的 BeanDefinition
对象作为核心元数据表示进行操作。这是使Spring容器如此灵活和可扩展的本质。
BeanFactory
或 ApplicationContext
?本节解释了 BeanFactory
和 ApplicationContext
容器级别之间的区别,以及对自启的影响。
你应该使用 ApplicationContext
,除非你有很好的理由不这样做,用 GenericApplicationContext
和它的子类 AnnotationConfigApplicationContext
作为自定义引导的通用实现。这些是Spring核心容器的主要入口点,用于所有常见目的:加载配置文件、触发类路径扫描、以编程方式注册Bean定义和带注释的类,以及(从 5.0 开始)注册功能Bean定义。
因为 ApplicationContext
包含了 BeanFactory
的所有功能,所以通常推荐使用它而不是普通的 BeanFactory
,除非在需要完全控制Bean处理的情况下。在 ApplicationContext
( 例如 GenericApplicationContext
实现 ) 中,通过约定 ( 即通过Bean名称或Bean类型—特别是后处理器 ) 检测几种Bean,而普通的 DefaultListableBeanFactory
对任何特殊Bean 都是不可知的。
对于许多扩展的容器特性,例如注释处理和AOP代理,BeanPostProcessor
是必不可少的。如果只使用普通的 DefaultListableBeanFactory
,则默认情况下不会检测和激活此类后处理器。这种情况可能会令人困惑,因为Bean配置实际上没有任何问题。相反,在这种情况下,容器需要通过额外的设置来完全引导。
下表列出了由 BeanFactory
和 ApplicationContext
接口及实现提供的特性。
特征 | BeanFactory | ApplicationContext |
---|---|---|
Bean 实例化 / 装配 | Yes | Yes |
集成的生命周期管理 | No | Yes |
BeanPostProcessor 自动注册 | No | Yes |
BeanFactoryPostProcessor 自动注册 | No | Yes |
MessageSource 方便访问(用于国际化) | No | Yes |
ApplicationEvent 内置发布机制 | No | Yes |
要显式地向 DefaultListableBeanFactory
注册一个Bean后处理器,你需要通过编程方式调用 addBeanPostProcessor
,如下例所示:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 用bean定义填充工厂
// 现在注册任何需要的BeanPostProcessor实例
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// 现在开始使用工厂
要将 BeanFactoryPostProcessor
应用到一个普通的 DefaultListableBeanFactory
,你需要调用它的 postProcessBeanFactory
方法,如下面的例子所示:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
// 从属性文件中引入一些属性值
PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
// 现在,实际进行替换
cfg.postProcessBeanFactory(factory);
在这两种情况下,显式的注册步骤都不方便,这就是为什么在Spring支持的应用程序中,各种 ApplicationContext
变量比普通的 DefaultListableBeanFactory
更受欢迎,特别是在典型的企业设置中依赖 BeanFactoryPostProcessor
和 BeanPostProcessor
实例来扩展容器功能时。
一个
AnnotationConfigApplicationContext
注册了所有常见的注释后处理器,并可能通过配置注释在底层引入额外的处理器,比如@EnableTransactionManagement
。在 Spring的基于注释的配置模型的抽象级别上,Bean后处理器的概念仅仅成为内部容器的细节。