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
实例来在典型的企业设置中扩展容器功能时。
|