# 1.16 BeanFactory

BeanFactory API为Spring的IOC功能提供了基础。其特定的契约主要用于与Spring和相关第三方框架的其他部分集成，其默认的ListableBeanFactory实现是更高级别GenericApplicationContext容器中的关键委托。

BeanFactory和相关接口（如BeanFactoryAware、InitializingBean、DisposableBean）是其他框架组件的重要集成点。通过不需要任何注解甚至反射，它们允许容器及其组件之间非常有效的交互。应用程序级bean可以使用相同的回调接口，但通常更倾向于通过注解或编程配置进行声明性依赖项注入。

请注意，核心BeanFactory API级别及其DefaultListableBeanFactory实现不会使用使用配置格式或任何组件注解。所有这些风格都通过扩展（如xmlbeanDefinitionReader和autowiredAnnotationBeanPostProcessor）传入，并作为核心元数据表示对共享BeanDefinition对象进行操作。这就是使Spring容器如此灵活和可扩展的本质所在。

## 1.16.1 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实例化和注入                   | Yes         | Yes                |
| 和生命周期集成                      | No          | Yes                |
| 自动BeanPostProcessor注册        | No          | Yes                |
| 自动BeanFactoryPostProcessor注册 | No          | Yes                |
| MessageSource便捷访问（内部）        | No          | Yes                |
| 内置的ApplicationEvent发布机制      | No          | yes                |

显示使用DefaultListableBeanFactory注册bean的post-processor， 你需要在程序中调用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
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));

// now actually do the replacement
cfg.postProcessBeanFactory(factory);
```

在这两种情况下，显式注册步骤都不方便，这就是为什么在支持Spring的应用程序中，各种ApplicationContext变量比普通的defaultListableBeanFactory更受欢迎，特别是在典型企业应用中，依赖BeanFactoryPostProcessor和BeanPostProcessor实例实现扩展容器功能时。

> AnnotationConfigApplicationContext注册了所有常见的注解后处理程序，并可以通过配置注解（如@EnableTransactionManagement）将其他处理程序置于覆盖范围内。在Spring基于注解的配置模型的抽象级别上，bean后处理器的概念变成了一个更内部的容器细节。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.flydean.com/spring-framework-documentation5/core-technologies/1.the-ioc-container/1.16the-beanfactory.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
