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 实例化/装配 |
是 |
是 |
集成生命周期管理 |
否 |
是 |
自动 |
否 |
是 |
自动 |
否 |
是 |
便捷的 |
否 |
是 |
内置 |
否 |
是 |
要将 bean 后处理器显式注册到 DefaultListableBeanFactory
,您需要以编程方式调用 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
实例来实现扩展容器功能时。
|