Spring IoC容器:BeanFactory API

https://docs.spring.io/spring-framework/reference/core/beans/beanfactory.html

BeanFactory API 提供了 Spring 控制反转(IoC)功能的基础,其特定接口主要与其它Spring 组件以及相关的第三方框架集成使用,而它的 DefaultListableBeanFactory 实现是高级 GenericApplicationContext 容器中的一个关键代理。

BeanFactory 及相关接口(如 BeanFactoryAwareInitializingBeanDisposableBean)是其它框架组件的重要集成点。它们不要求任何注解或甚至反射,允许容器与其组件之间非常高效的交互。应用级别的 bean 可能会使用相同的回调接口,但通常更倾向于通过注解或编程配置来声明式地注入依赖。

核心的 BeanFactory API 层面及其 DefaultListableBeanFactory 实现并不对配置格式或任何组件注解做出假设。所有这些变体都是通过扩展(如 XmlBeanDefinitionReaderAutowiredAnnotationBeanPostProcessor)引入的,并且操作共享的 BeanDefinition 对象作为核心元数据表示。这是使得 Spring 容器如此灵活和可扩展的本质所在。

BeanFactory 还是 ApplicationContext?

本节解释了 BeanFactoryApplicationContext 容器级别之间的差异,以及它们对引导过程的影响。

除非你有充分的理由不这么做,否则应该使用 ApplicationContext,其中 GenericApplicationContext 及其子类 AnnotationConfigApplicationContext 是自定义引导常见的实现。这些是进入 Spring 核心容器的主要入口,适用于所有常见用途:加载配置文件、触发类路径扫描、以编程方式注册 bean 定义和注解类,以及(自 5.0 版本起)注册函数式 bean 定义。

因为 ApplicationContext 包含了 BeanFactory 的所有功能,所以通常推荐使用它而不是普通的 BeanFactory,除非在需要完全控制 bean 处理的场景中。在 ApplicationContext 内部(例如 GenericApplicationContext 实现),多种类型的 beans 可以通过约定检测到(即通过 bean 名称或 bean 类型——特别是后处理器),而一个普通的 DefaultListableBeanFactory 对任何特殊的 beans 都是不可知的。

对于许多扩展的容器特性,如注解处理和 AOP 代理,BeanPostProcessor 扩展点是必不可少的。如果仅使用普通的 DefaultListableBeanFactory,这样的后处理器默认不会被检测和激活。这种情况可能会令人困惑,因为你的 bean 配置实际上没有任何问题。相反,在这种情况下,需要通过额外的设置来完全引导容器。

下表列出了 BeanFactoryApplicationContext 接口及其实现提供的特性。
在这里插入图片描述

要显式地向 DefaultListableBeanFactory 注册一个 bean 后处理器,你需要像下面的例子那样以编程方式调用 addBeanPostProcessor

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

要将 BeanFactoryPostProcessor 应用于普通的 DefaultListableBeanFactory,需要调用其 postProcessBeanFactory 方法,如下例所示:

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);

在这两种情况下,显式注册步骤都不方便,这就是为什么在 Spring 支持的应用程序中,尤其是在典型的企业环境中依赖 BeanFactoryPostProcessorBeanPostProcessor 实例来扩展容器功能时,更倾向于使用各种 ApplicationContext 变体而不是普通的 DefaultListableBeanFactory

AnnotationConfigApplicationContext 注册了所有常见的注解后处理器,并且可能通过配置注解(如 @EnableTransactionManagement)在底层引入额外的处理器。在 Spring 基于注解的配置模型的抽象层面上,bean 后处理器的概念变成了容器内部的一个细节。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值