The BeanFactory API

BeanFactory API 为 Spring 的 IoC 功能提供了基础。它的特定协定主要用于与 Spring 的其他部分和相关的第三方框架集成,而它的 DefaultListableBeanFactory 实现是高级别 GenericApplicationContext 容器中的关键委托。

The BeanFactory API provides the underlying basis for Spring’s IoC functionality. Its specific contracts are mostly used in integration with other parts of Spring and related third-party frameworks, and its DefaultListableBeanFactory implementation is a key delegate within the higher-level GenericApplicationContext container.

BeanFactory 和相关接口(如 BeanFactoryAwareInitializingBeanDisposableBean)是其他框架组件的重要集成点。通过不需要任何注解甚至反射,它们允许容器及其组件之间进行非常有效的交互。应用程序级 Bean 可以使用相同的回调接口,但通常首选声明式依赖注入,通过注解或通过程序化配置实现。

BeanFactory and related interfaces (such as BeanFactoryAware, InitializingBean, DisposableBean) are important integration points for other framework components. By not requiring any annotations or even reflection, they allow for very efficient interaction between the container and its components. Application-level beans may use the same callback interfaces but typically prefer declarative dependency injection instead, either through annotations or through programmatic configuration.

请注意,核心 BeanFactory API 级别及其 DefaultListableBeanFactory 实现不会对配置格式或要使用的任何组件注解做出假设。所有这些特性都通过扩展(如 XmlBeanDefinitionReaderAutowiredAnnotationBeanPostProcessor)进入,并在共享的 BeanDefinition 对象上作为核心元数据表示进行操作。这就是 Spring 的容器如此灵活且可扩展的原因。

Note that the core BeanFactory API level and its DefaultListableBeanFactory implementation do not make assumptions about the configuration format or any component annotations to be used. All of these flavors come in through extensions (such as XmlBeanDefinitionReader and AutowiredAnnotationBeanPostProcessor) and operate on shared BeanDefinition objects as a core metadata representation. This is the essence of what makes Spring’s container so flexible and extensible.

BeanFactory or ApplicationContext?

本部分介绍 BeanFactoryApplicationContext 容器级别之间的差异,以及对引导的影响。

This section explains the differences between the BeanFactory and ApplicationContext container levels and the implications on bootstrapping.

除非有充分的理由不这样做,否则应使用 ApplicationContext,使用 GenericApplicationContext 及其子类 AnnotationConfigApplicationContext 作为自定义引导的常见实现。这些是 Spring 的核心容器的通用实现,适用于所有常见目的:加载配置文件、触发类路径扫描、以编程方式注册 Bean 定义和带注解的类,以及(从 5.0 版开始)注册功能性 Bean 定义。

You should use an ApplicationContext unless you have a good reason for not doing so, with GenericApplicationContext and its subclass AnnotationConfigApplicationContext as the common implementations for custom bootstrapping. These are the primary entry points to Spring’s core container for all common purposes: loading of configuration files, triggering a classpath scan, programmatically registering bean definitions and annotated classes, and (as of 5.0) registering functional bean definitions.

由于 ApplicationContext 包含 BeanFactory 的所有功能,所以通常建议使用 ApplicationContext 而非普通的 BeanFactory,除非需要对 Bean 处理进行完全控制。在 ApplicationContext(如 GenericApplicationContext 实现)内部,根据惯例(即按 Bean 名称或按 Bean 类型 - 特别是后置处理器)检测到几种 Bean,而普通的 DefaultListableBeanFactory 不识别任何特殊 Bean。

Because an ApplicationContext includes all the functionality of a BeanFactory, it is generally recommended over a plain BeanFactory, except for scenarios where full control over bean processing is needed. Within an ApplicationContext (such as the GenericApplicationContext implementation), several kinds of beans are detected by convention (that is, by bean name or by bean type — in particular, post-processors), while a plain DefaultListableBeanFactory is agnostic about any special beans.

对于许多扩展的容器功能,例如注解处理和 AOP 代理,xref:core/beans/factory-extension.adoc#beans-factory-extension-bpp[BeanPostProcessor`扩展点至关重要。如果您只使用纯`DefaultListableBeanFactory,则默认情况下无法检测并激活此类后置处理器。这种情况可能会令人困惑,因为您的 Bean 配置实际上并没有什么问题。相反,在这种情况下,需要通过附加设置完全引导容器。

For many extended container features, such as annotation processing and AOP proxying, the BeanPostProcessor extension point is essential. If you use only a plain DefaultListableBeanFactory, such post-processors do not get detected and activated by default. This situation could be confusing, because nothing is actually wrong with your bean configuration. Rather, in such a scenario, the container needs to be fully bootstrapped through additional setup.

下表列出了 BeanFactoryApplicationContext 接口和实现提供的功能。

The following table lists features provided by the BeanFactory and ApplicationContext interfaces and implementations.

Table 1. Feature Matrix
Feature BeanFactory ApplicationContext

Bean instantiation/wiring

Yes

Yes

Integrated lifecycle management

No

Yes

Automatic BeanPostProcessor registration

No

Yes

Automatic BeanFactoryPostProcessor registration

No

Yes

Convenient MessageSource access (for internationalization)

No

Yes

Built-in ApplicationEvent publication mechanism

No

Yes

要使用 DefaultListableBeanFactory 明确注册 bean 后处理器,需要以编程方式调用 addBeanPostProcessor,如下例所示:

To explicitly register a bean post-processor with a DefaultListableBeanFactory, you need to programmatically call addBeanPostProcessor, as the following example shows:

  • 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 方法,如下例所示:

To apply a BeanFactoryPostProcessor to a plain DefaultListableBeanFactory, you need to call its postProcessBeanFactory method, as the following example shows:

  • 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 的原因,尤其是在在典型的企业设置中依赖 BeanFactoryPostProcessorBeanPostProcessor 实例以扩展容器功能的情况下。

In both cases, the explicit registration steps are inconvenient, which is why the various ApplicationContext variants are preferred over a plain DefaultListableBeanFactory in Spring-backed applications, especially when relying on BeanFactoryPostProcessor and BeanPostProcessor instances for extended container functionality in a typical enterprise setup.

AnnotationConfigApplicationContext 注册了所有常见的注释后处理器,并可能通过配置注释(例如 @EnableTransactionManagement)引入其他处理器。在 Spring 基于注释的配置模型的抽象层级中,bean 后处理器的概念变成了纯粹的内部容器细节。

An AnnotationConfigApplicationContext has all common annotation post-processors registered and may bring in additional processors underneath the covers through configuration annotations, such as @EnableTransactionManagement. At the abstraction level of Spring’s annotation-based configuration model, the notion of bean post-processors becomes a mere internal container detail.