# 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后处理器的概念变成了一个更内部的容器细节。
