BeanFactory
API
BeanFactory
API 提供了 Infra IoC 功能的基础。它的具体契约大多用于与 Infra
的其他部分以及相关的第三方框架集成,其 StandardBeanFactory
实现是高级 GenericApplicationContext
容器内的一个关键委托。
BeanFactory
及其相关接口(如 BeanFactoryAware
、InitializingBean
、DisposableBean
)
是其他框架组件的重要集成点。通过不需要任何注解甚至反射,它们允许容器与其组件之间进行非常高效的交互。
应用级别的 Bean 可以使用相同的回调接口,但通常更喜欢声明式依赖注入,可以通过注解或编程配置来实现。
请注意,核心 BeanFactory
API 层及其 StandardBeanFactory
实现不对要使用的配置格式或任何组件注解做出假设。所有这些变体都通过扩展(如 XmlBeanDefinitionReader
和 AutowiredAnnotationBeanPostProcessor
)进入,并在共享的 BeanDefinition
对象上操作作为核心元数据表示。
这就是使 Infra 容器如此灵活和可扩展的本质。
BeanFactory
vs ApplicationContext
?
这一部分解释了 BeanFactory
和 ApplicationContext
容器级别之间的区别,以及对引导的影响。
除非有充分理由不这样做,否则应该使用 ApplicationContext
,其常见的自定义引导实现为
GenericApplicationContext
及其子类 AnnotationConfigApplicationContext
。
这些是 Infra 核心容器的主要入口点,用于所有通用目的:加载配置文件,触发类路径扫描,
以编程方式注册 bean 定义和注解类,以及注册功能 bean 定义。
因为 ApplicationContext
包含了 BeanFactory
的所有功能,所以通常建议使用 ApplicationContext
而不是普通的 BeanFactory
,除非需要对 bean 处理具有完全控制权。在 ApplicationContext
内(例如 GenericApplicationContext
实现),按照约定检测到几种类型的 bean(即,按照 bean 名称或 bean 类型 — 特别是后处理器)
,而普通的 StandardBeanFactory
对于任何特殊的 bean 都是不可知的。
对于许多扩展容器功能,例如注解处理和 AOP 代理,BeanPostProcessor
扩展点
是必不可少的。如果仅使用普通的 StandardBeanFactory
,这样的后处理器将不会被默认检测和激活。
这种情况可能会令人困惑,因为您的 bean 配置实际上并没有问题。相反,在这种情况下,需要通过额外的设置完全引导容器。
以下表格列出了 BeanFactory
和 ApplicationContext
接口及其实现提供的功能。
特性 | BeanFactory |
ApplicationContext |
---|---|---|
Bean 实例化/装配 |
Yes |
Yes |
集成的生命周期管理 |
No |
Yes |
|
No |
Yes |
|
No |
Yes |
好用的 |
No |
Yes |
内置的 |
No |
Yes |
要将一个Bean后处理器明确注册到`StandardBeanFactory`,你需要以编程方式调用`addBeanPostProcessor`,就像以下示例所示:
StandardBeanFactory factory = new StandardBeanFactory();
// 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
要将`BeanFactoryPostProcessor`应用于普通的`StandardBeanFactory`,你需要调用其`postProcessBeanFactory`方法,就像以下示例所示:
StandardBeanFactory factory = new StandardBeanFactory();
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);
在这两种情况下,明确注册步骤都不太方便,这就是为什么在 Infra 支持的应用程序中,各种 ApplicationContext
变体优先于普通的 StandardBeanFactory
,特别是在典型企业设置中依赖于 BeanFactoryPostProcessor
和 BeanPostProcessor
实例以扩展容器功能时。
|