BeanFactory
API
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 实例化/连接 |
是 |
是 |
集成生命周期管理 |
否 |
是 |
自动 |
否 |
是 |
自动 |
否 |
是 |
便捷的 |
否 |
是 |
内置的 |
否 |
是 |
要使用DefaultListableBeanFactory
显式注册 Bean 后置处理器,需要以编程方式调用addBeanPostProcessor
,如下例所示
-
Java
-
Kotlin
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// populate the factory with bean definitions
// now register any needed BeanPostProcessor instances
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// now start using the factory
val factory = DefaultListableBeanFactory()
// populate the factory with bean definitions
// now register any needed BeanPostProcessor instances
factory.addBeanPostProcessor(AutowiredAnnotationBeanPostProcessor())
factory.addBeanPostProcessor(MyBeanPostProcessor())
// now start using the factory
要将BeanFactoryPostProcessor
应用于普通DefaultListableBeanFactory
,需要调用其postProcessBeanFactory
方法,如下例所示
-
Java
-
Kotlin
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
// bring in some property values from a Properties file
PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
// now actually do the replacement
cfg.postProcessBeanFactory(factory);
val factory = DefaultListableBeanFactory()
val reader = XmlBeanDefinitionReader(factory)
reader.loadBeanDefinitions(FileSystemResource("beans.xml"))
// bring in some property values from a Properties file
val cfg = PropertySourcesPlaceholderConfigurer()
cfg.setLocation(FileSystemResource("jdbc.properties"))
// now actually do the replacement
cfg.postProcessBeanFactory(factory)
在这两种情况下,显式注册步骤都很不方便,这就是为什么在 Spring 支持的应用程序中各种ApplicationContext
变体比普通DefaultListableBeanFactory
更受欢迎,尤其是在依赖BeanFactoryPostProcessor
和BeanPostProcessor
实例以在典型的企业设置中扩展容器功能时。
|