这一篇主要简单有个印象就好,不要太过纠结强行记忆,很多东西后面会见到,结合例子才能更好的理解。

1. BeanFactory 和 子接口

image.png
这两篇文章,我们就根据 Spring 的官方文档,对 BeanFactory 和 ApplicationContext 进行一个深入的了解和分析。我这里使用的是当前最新的 5.3.16 的版本,大家可以自行选择,现在 5.x 版本是最常用的了。

这一篇先谈谈 BeanFactory 。

打开第一个 关于 BeanFactory 的 API DOC 的时候,在介绍部分就能看到非常长的一段话,我们分段落翻译和了解一下。

1.1 BeanFactory

1.1.1 BeanFactory 和其子接口的地位

The root interface for accessing a Spring bean container. This is the basic client view of a bean container; further interfaces such as ListableBeanFactory and ConfigurableBeanFactory are available for specific purposes.

用于访问 Spring bean 容器的根接口。 这是 bean 容器的基本客户端视图,更多接口,例如 ListableBeanFactory 和 ConfigurableBeanFactory 可用于特定目的。

这段话能表示,BeanFactory Spring 中用来管理 Bean 的最基本的接口,其它的一些子接口都是为了实现一些额外的特性,比如层次性、可搜索性、可配置性等。

1.1.2 BeanFactory 作用域

This interface is implemented by objects that hold a number of bean definitions, each uniquely identified by a String name. Depending on the bean definition, the factory will return either an independent instance of a contained object (the Prototype design pattern), or a single shared instance (a superior alternative to the Singleton design pattern, in which the instance is a singleton in the scope of the factory). Which type of instance will be returned depends on the bean factory configuration: the API is the same. Since Spring 2.0, further scopes are available depending on the concrete application context (e.g. “request” and “session” scopes in a web environment).

此接口由包含多个 bean 定义的对象实现,每个定义由字符串 “name” 唯一标识。根据bean的定义,工厂将返回包含对象的独立实例 (原型设计模式) 或单个共享实例 (单例设计模式的高级替代方案,其中实例是工厂范围内的单例)。返回哪种类型的实例取决于bean工厂配置: API相同。自Spring 2.0以来,根据具体的应用程序上下文 (例如网络环境中的 “请求” 和 “会话” 范围),可以使用更多的范围。

Spring 在默认刚设计的时候,只有 singleton 和 prototype 两种,后来 2.0 后新增了 request 和 session ,再后来又新增了 global session 和 websocket 作用域。而我们统一通过 @Scope 注解进行了指定配置,通过 BeanFactory 创建出来。

1.1.3 BeanFactory 的环境和配置

The point of this approach is that the BeanFactory is a central registry of application components, and centralizes configuration of application components (no more do individual objects need to read properties files, for example). See chapters 4 and 11 of “Expert One-on-One J2EE Design and Development” for a discussion of the benefits of this approach.

这种方法的要点是,BeanFactory是应用程序组件的中央注册表,并且集中了应用程序组件的配置 (例如,不再需要单个对象读取属性文件)。有关这种方法的好处的讨论,请参见 “专家一对一J2EE设计和开发” 的第4章和第11章。

这一段告诉我们,BeanFactory 是所有 Bean 的中央注册表,所有 bean 的创建和保存都在它中管理。而且它还集成了关于配置的信息,就类似我们之前通过 load properties 文件将一些值赋值在 Bean 对象中。

不过再 Spring 3.1 后,Environment 这个概念出现了,现在的 Spring 都是通过它来去做环境和配置。这个我们后面会单独出文章去看。

1.1.4 BeanFactory 推荐依赖注入(DI)而不是依赖查找(DL)

Note that it is generally better to rely on Dependency Injection (“push” configuration) to configure application objects through setters or constructors, rather than use any form of “pull” configuration like a BeanFactory lookup. Spring’s Dependency Injection functionality is implemented using this BeanFactory interface and its subinterfaces.

请注意,通常最好依靠依赖注入 (“推送” 配置) 通过setter或构造函数来配置应用程序对象,而不是使用任何形式的 “拉” 配置,如BeanFactory查找。Spring的依赖注入功能是使用此BeanFactory接口及其子接口实现的。

这一段其实主要是 Spring 对于 IOC 实现上的选择推荐,它认为依赖注入,就像 “推” 的概念,而依赖查找就像是 “拉” 的概念,例如需要什么组件,就自己去 IOC 容器中去拉取。

1.1.5 BeanFactory 支持多种数据源

Normally a BeanFactory will load bean definitions stored in a configuration source (such as an XML document), and use the org.springframework.beans package to configure the beans. However, an implementation could simply return Java objects it creates as necessary directly in Java code. There are no constraints on how the definitions could be stored: LDAP, RDBMS, XML, properties file, etc. Implementations are encouraged to support references amongst beans (Dependency Injection).

通常,BeanFactory会加载存储在配置源 (例如XML文档) 中的bean定义,并使用org.springframework.bean包来配置bean。但是,实现可以简单地返回它在Java代码中根据需要直接创建的Java对象。关于如何存储定义没有限制: LDAP、RDBMS、XML、属性文件等。鼓励实施以支持bean中的引用 (依赖注入)。

我们最常用的是通过 xml 或者 注解,而 Spring 本身支持的源的类型其实有很多,这些数据源中存储的信息是关于 Bean 的定义,这个部分会在后面 关于 BeanDefinition 的文章中介绍。

1.1.6 BeanFactory 的层次性

In contrast to the methods in ListableBeanFactory, all of the operations in this interface will also check parent factories if this is a HierarchicalBeanFactory. If a bean is not found in this factory instance, the immediate parent factory will be asked. Beans in this factory instance are supposed to override beans of the same name in any parent factory.

与 ListableBeanFactory 中的方法相反,此界面中的所有操作还将检查父工厂,如果这是 HierarchicalBeanFactory。如果在此工厂实例中找不到bean,将直接查询父工厂。此工厂实例中的bean应该覆盖任何父工厂中同名的bean。

这段听起来太绕了,其实就是说 BeanFactory 是支持父子结构的,这个父子结构的概念由 HierarchicalBeanFactory 实现,具体下面会讲解。

1.1.7 BeanFactory 中设有完整的生命周期

Bean factory implementations should support the standard bean lifecycle interfaces as far as possible. The full set of initialization methods and their standard order is:

  1. BeanNameAware’s setBeanName
  2. BeanClassLoaderAware’s setBeanClassLoader
  3. BeanFactoryAware’s setBeanFactory
  4. EnvironmentAware’s setEnvironment
  5. EmbeddedValueResolverAware’s setEmbeddedValueResolver
  6. ResourceLoaderAware’s setResourceLoader (only applicable when running in an application context)
  7. ApplicationEventPublisherAware’s setApplicationEventPublisher (only applicable when running in an application context)
  8. MessageSourceAware’s setMessageSource (only applicable when running in an application context)
  9. ApplicationContextAware’s setApplicationContext (only applicable when running in an application context)
  10. ServletContextAware’s setServletContext (only applicable when running in a web application context)
  11. postProcessBeforeInitialization methods of BeanPostProcessors
  12. InitializingBean’s afterPropertiesSet
  13. a custom init-method definition
  14. postProcessAfterInitialization methods of BeanPostProcessors

On shutdown of a bean factory, the following lifecycle methods apply:

  1. postProcessBeforeDestruction methods of DestructionAwareBeanPostProcessors
  2. DisposableBean’s destroy
  3. a custom destroy-method definition

上面这段就说明了,BeanFactory 实现了尽可能支持标准bean生命周期接口。以及给出了全套初始化方法及其标准的顺序。最下面是关于关闭 BeanFactory 时的一些方法。

1.2 HierarchicalBeanFactory

地址:HierarchicalBeanFactory

Sub-interface implemented by bean factories that can be part of a hierarchy. The corresponding setParentBeanFactory method for bean factories that allow setting the parent in a configurable fashion can be found in the ConfigurableBeanFactory interface.

可作为层次结构一部分的bean工厂实现的子接口。 bean工厂的相应setParentBeanFactory方法允许以可配置的方式设置父级,可以在配置beanfactory界面中找到。

HierarchicalBeanFactory 是 BeanFactory 的一个子接口,而通过它就可以实现层次性。

Modifier and Type Method and Description
boolean containsLocalBean(String name)
Return whether the local bean factory contains a bean of the given name, ignoring beans defined in ancestor contexts.
BeanFactory getParentBeanFactory()
Return the parent bean factory, or null if there is none.

通过上面表格,其实能看到其下面有两个方法,containsLocalBean 是用来检查本地的容器中是否存在指定名称的 bean,如果有就不去找父级别的 BeanFactory 了。而 getParentBeanFactory 就是用来向上获取到父级别的 BeanFactory 接口。
所以在我们前面 getBean 的时候,其实就会先从当前的 BeanFactory 中去找,如果没有就会向上找,如果最终也没找到,则会抛出 NoSuchBeanDefinitionException 异常。

这里就能引申出一个思考?我们的 bean 默认或者显式的设置为单例的,那么如果当前的 BeanFactory 中已经有了这个 bean ,那么父级别的 BeanFactory 中也会有同样的 bean 吗?
答案是肯定的,因为虽然不同的 BeanFactory 存在父子关系,但是它们从本质上还是不同的容器,所以我们设置的单例,其实是针对一个容器而言的,如果从整个层次结构的多容器的角度来看,其实它并不是单例的了。

至于父级别的 BeanFactory 是如何被赋值的,这是通过 ConfigurableBeanFactory 的 setParentBeanFactory 方法实现的,这个我们后面进再说。

1.3 ListableBeanFactory

地址:ListableBeanFactory
就通过 Listable 其实就能猜出这个 BeanFactory 的大意。就是可列举,所以它一定和列举容器中的 Bean 有关。

1.3.1 列举出所有 Bean

Extension of the BeanFactory interface to be implemented by bean factories that can enumerate all their bean instances, rather than attempting bean lookup by name one by one as requested by clients. BeanFactory implementations that preload all their bean definitions (such as XML-based factories) may implement this interface.

BeanFactory 的扩展接口将由可以枚举其所有bean实例的bean工厂实现,而不是根据客户端的请求逐个尝试按名称查找bean。预加载其所有bean定义 (例如基于XML的工厂) 的BeanFactory实现可以实现此接口。

这段也非常好理解,其实就是在获取到 BeanFactory 的时候,可以直接把容器中的所有 Bean 一下子拿出来,这样就不用我们一个一个去取出,就如后面还提到了 definitions 这个会在后面的 BeanDefinition 时了解到。

1.3.2 只获取当前容器的 Bean

If this is a HierarchicalBeanFactory, the return values will not take any BeanFactory hierarchy into account, but will relate only to the beans defined in the current factory. Use the BeanFactoryUtils helper class to consider beans in ancestor factories too.

如果这是一个 HierarchicalBeanFactory,返回值将不考虑任何BeanFactory层次结构,但仅与当前工厂中定义的bean相关。使用BeanFactoryUtils 助手类也要考虑父工厂中的 Bean。

上面我们已经提到了 HierarchicalBeanFactory 实现了 BeanFactory 的层级结构,而对于 ListableBeanFactory 来说,Spring 选择了只获取当前层级,即当前容器中的 Bean,如果想要获取父级别的 Bean,可以通过 BeanFactoryUtisl 其中有一些 IncludingAncestors 这样提示包含父类的方法。

1.3.3 有选择性的 list

The methods in this interface will just respect bean definitions of this factory. They will ignore any singleton beans that have been registered by other means like ConfigurableBeanFactory‘s registerSingleton method, with the exception of getBeanNamesForType and getBeansOfType which will check such manually registered singletons too. Of course, BeanFactory’s getBean does allow transparent access to such special beans as well. However, in typical scenarios, all beans will be defined by external bean definitions anyway, so most applications don’t need to worry about this differentiation.

这个界面中的方法将只尊重这个工厂的bean定义。他们将忽略任何通过其他方式注册的单例 bean,ConfigurableBeanFactory 的 registerSingleton 方法,除了 getBeanNamesForType 和 getBeansOfType,它们也将检查此类手动注册的单例。当然,BeanFactory的getBean也允许透明地访问这种特殊的 bean。但是,在典型情况下,无论如何所有bean都将由外部bean定义来定义,因此大多数应用程序不必担心这种差异。

ListableBeanFactory 刚开始我们从字面上就能只带它是可以帮助我们列出或者取出容器中的 Bean 的,但是这段话却告诉我们,它的展示也是有策略的,例如自己手动注册的一些 bean,就不会被列出,而通过我们常规 xml 和注解注入的 bean 则能够被正常取出。

一起来看一下为什么,创建 Student 和 Teacher 两个 bean,然后在 xml 中配置一个 Student 的 bean

  1. public class Test {
  2. public static void main(String[] args) {
  3. ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  4. DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory) context.getBeanFactory();
  5. System.out.println("加载完 bean.xml 后");
  6. Stream.of(context.getBeanDefinitionNames()).forEach(System.out::println);
  7. System.out.println("-------------------------------");
  8. listableBeanFactory.registerSingleton("teacher", new Teacher());
  9. System.out.println("加载完 bean.xml 且手动注册了一个 Bean 后");
  10. Stream.of(context.getBeanDefinitionNames()).forEach(System.out::println);
  11. System.out.println("-------------------------------");
  12. System.out.println("容器中是否存在 teacher 这个 bean: " + listableBeanFactory.getBean("teacher"));
  13. System.out.println("容器中的所有 Teacher 类型的 bean: " + Arrays.toString(listableBeanFactory.getBeanNamesForType(Teacher.class)));
  14. }
  15. }

运行结果

加载完 bean.xml 后
com.ideal.my_factory.Student#0
-------------------------------
加载完 bean.xml 且手动注册了一个 Bean 后
com.ideal.my_factory.Student#0
-------------------------------
容器中是否存在 teacher 这个 bean: com.ideal.my_factory.Teacher@36b4cef0
容器中的所有 Teacher 类型的 bean: [teacher]

可以看到,我们读取 bean 的时候,只读取到了在 bean.xml 中配置了的 Student。我们即使通过 registerSingleton 方法注册了一个 bean,也没有效果。但是我们去主动查询是否容器中含有这个 bean,结果显示这个 bean 也是实实在在存在的。

为什么这么做呢?

大家可以在 AbstractApplicationContext 中的 prepareBeanFactory 方法中得到答案,在这个方法中,很明显 Spring 自己也注册了一些 bean 出来,例如 environment、sstemXxxx、applicationXxxx 。而这些 bean 其实都是 Spring 自身内部使用的。就例如我们在 IDEA 中使用 Maven 的时候,默认的仓库地址就是 ${user.home}/.m2/repository 这样的字眼,如果我们不修改配置,不打开显示隐藏文件的时候,我们其实对这个目录和文件是无感知的。因为这个内容,对于只是想找一个文件的人,可能并无用处,而只是对真正使用 Maven 的人有用。所以为了干净,也为了防止其他人误操作这些文件或者文件夹,选择了隐藏。

if (!beanFactory.containsLocalBean("environment")) {
    beanFactory.registerSingleton("environment", this.getEnvironment());
}

if (!beanFactory.containsLocalBean("systemProperties")) {
    beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
}

if (!beanFactory.containsLocalBean("systemEnvironment")) {
    beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
}

if (!beanFactory.containsLocalBean("applicationStartup")) {
    beanFactory.registerSingleton("applicationStartup", this.getApplicationStartup());
}

1.3.4 接口中的方法不适合频繁调用

NOTE: With the exception of getBeanDefinitionCount and containsBeanDefinition, the methods in this interface are not designed for frequent invocation. Implementations may be slow.

注意:除了getbeandefintioncount和containsbeandefin,此接口中的方法不是为频繁调用而设计的。实现可能会很慢。

1.4 AutowireCapableBeanFactory

地址:AutowireCapableBeanFactory
顾名思义,这是一个具有自动装配/自动注入能力的 Bean Factory,我们接着看文档。

1.4.1 外部 bean 的自动装配

Extension of the BeanFactory interface to be implemented by bean factories that are capable of autowiring, provided that they want to expose this functionality for existing bean instances.

BeanFactory接口的扩展,由能够自动装配的bean工厂实现,前提是它们希望为现有的bean实例公开此功能

AutowireCapableBeanFactory 本身是支持自动注入的,而同样它还能帮助一些外部的 bean,就是不被 Spring 管理的 bean 实现自动装配,有点迷糊,就接着看下一点。

1.4.2 集成其它框架

This subinterface of BeanFactory is not meant to be used in normal application code: stick to BeanFactory or ListableBeanFactory for typical use cases. Integration code for other frameworks can leverage this interface to wire and populate existing bean instances that Spring does not control the lifecycle of. This is particularly useful for WebWork Actions and Tapestry Page objects, for example.

BeanFactory的这个子接口并不意味着在正常的应用程序代码中使用: 坚持 BeanFactory 或 ListableBeanFactory 对于典型用例。 其他框架的集成代码可以利用此接口来连接和填充Spring不控制其生命周期的现有bean实例。例如,这对于WebWork操作和Tapestry页面对象特别有用。

这两段话的意思就是,一般我们自己用的时候,不使用 AutowireCapableBeanFactory,和其它框架进行集成的时候再用,比如和一些其它框架集成的时候,一些 bean 不被 Spring 控制,但是又需要注入,就可以使用。

例如一个 Filter 是在 Tomcat 容器中的,而在其 init 方法中就可以通过获取 AutowireCapableBeanFactory 实现自动装配到 Spring。

1.4.3 用的少但是可获取

Note that this interface is not implemented by ApplicationContext facades, as it is hardly ever used by application code. That said, it is available from an application context too, accessible through ApplicationContext’s ApplicationContext.getAutowireCapableBeanFactory() method.

请注意,这个接口不是由ApplicationContext facade实现的,因为应用程序代码很少使用它。也就是说,它也可以从应用上下文中获得,可以通过ApplicationContext的ApplicationContext. getautowirecapablebeanfactory()方法访问。

这句很简单,就是告诉我们,这个接口用的很少,但是我也给了大家获取的方式。

1.4.4 可以通过 BeanFactoryAware 注入

You may also implement the BeanFactoryAware interface, which exposes the internal BeanFactory even when running in an ApplicationContext, to get access to an AutowireCapableBeanFactory: simply cast the passed-in BeanFactory to AutowireCapableBeanFactory.

您也可以实现BeanFactoryAware接口,该接口公开内部的BeanFactory,即使在ApplicationContext中运行,以获得对AutowireCapableBeanFactory的访问:简单地将传入的BeanFactory转换为AutowireCapableBeanFactory。

1.5 ConfigurableBeanFactory

地址:ConfigurableBeanFactory

Configuration interface to be implemented by most bean factories. Provides facilities to configure a bean factory, in addition to the bean factory client methods in the BeanFactory interface. This bean factory interface is not meant to be used in normal application code: Stick to BeanFactory or ListableBeanFactory for typical needs. This extended interface is just meant to allow for framework-internal plug’n’play and for special access to bean factory configuration methods.

由大多数bean工厂实现的配置接口。除了BeanFactory接口中的bean工厂客户端方法外,还提供配置bean工厂的工具。 这个bean工厂接口并不打算用于普通的应用程序代码:对于典型的需求,请坚持使用BeanFactory或ListableBeanFactory。这个扩展的接口只是为了允许框架内部即插即用,以及对bean工厂配置方法的特殊访问。

ConfigurableBeanFactory 从字面意思也可以看出,就是提供一个具有一定配置能力的 BeanFactory,例如可以通过 set 为一些内容赋值,但是Spring 本身其实也并不推荐我们使用这个接口,还是让我们用最基本的 BeanFactory 或者 ApplicationContext,因为我们程序运行时,不应该再进行变动了,尤其是这种 set 操作。

2. BeanFactory 的部分实现类

在 IDEA 中生成一下 BeanFactory 的实现类,这个图片比较大,分辨率是没问题的,大家可以放大图片来看清晰的图片。
image.png

2.1 AbstractBeanFactory

2.1.1 它是 BeanFactory 的基础实现

Abstract base class for BeanFactory implementations, providing the full capabilities of the ConfigurableBeanFactory SPI. Does not assume a listable bean factory: can therefore also be used as base class for bean factory implementations which obtain bean definitions from some backend resource (where bean definition access is an expensive operation).

BeanFactory实现的抽象基类,提供了ConfigurableBeanFactory SPI的全部功能。不假设有一个可列出的bean工厂:因此也可以用作从后端资源(其中bean定义访问是一项开销很大的操作)获取bean定义的bean工厂实现的基类。

这一段就是说,AbstractBeanFactory 是 BeanFactory 下的一个抽象实现类,它所含有的是一些最基本的功能,而且它可以从配置源中获取 Bean 的定义信息。而提到的 SPI (Service Provider Interface) 是 JDK 自带的一种服务发现机制,简单的说就是预先在指定位置配置一些类,后面的文章也会提到。

2.1.2 对 bean 的支持

This class provides a singleton cache (through its base class DefaultSingletonBeanRegistry, singleton/prototype determination, FactoryBean handling, aliases, bean definition merging for child bean definitions, and bean destruction (DisposableBean interface, custom destroy methods). Furthermore, it can manage a bean factory hierarchy (delegating to the parent in case of an unknown bean), through implementing the HierarchicalBeanFactory interface.

这个类提供了一个单例缓存(通过它的基类DefaultSingletonBeanRegistry、单例/原型确定、FactoryBean处理、别名、子bean定义的bean定义合并和bean销毁(可丢弃的bean接口、自定义销毁方法)。此外,它还可以通过实现HierarchicalBeanFactory接口来管理bean工厂层次结构(在未知bean的情况下委托给父类)。

这一部分就提及了一下对 bean 的一些支持,例如一些层级结构我们是已经见过的,还有一些例如别名等等的支持我们还没见过,随着文章的更新会逐步提到。

2.1.3 模板方法

The main template methods to be implemented by subclasses are getBeanDefinition(java.lang.String) and createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[]), retrieving a bean definition for a given bean name and creating a bean instance for a given bean definition, respectively. Default implementations of those operations can be found in DefaultListableBeanFactory and AbstractAutowireCapableBeanFactory.

子类要实现的主要模板方法是getBeanDefinition(java.lang. string)和createBean(java.lang. string . string)。字符串,org.springframework.beans.factory.support。RootBeanDefinition、java.lang.Object[])、为给定的bean名称检索bean定义和为给定的bean定义创建bean实例。这些操作的默认实现可以在DefaultListableBeanFactory和AbstractAutowireCapableBeanFactory中找到。

这一段说明了 AbstractBeanFactory 其中实现了两个模板方法,并且进行了一些介绍,但是引申出的是,其实 Spring 中,使用了很多的模板方法设计模式,核心就是 “父类提供逻辑规范,子类提供具体实现”

2.2 AbstractAutowireCapableBeanFactory

地址:AbstractAutowireCapableBeanFactory

2.2.1 创建 bean

Abstract bean factory superclass that implements default bean creation, with the full capabilities specified by the RootBeanDefinition class. Implements the AutowireCapableBeanFactory interface in addition to AbstractBeanFactory’s createBean(java.lang.Class) method.

抽象bean工厂超类,实现了默认的bean创建,具有由RootBeanDefinition类指定的全部功能。除了AbstractBeanFactory的createBean(java.lang.Class)方法之外,还实现了AutowireCapableBeanFactory接口。

它继承了 AbstractBeanFactory 而且重写了 createBean 方法,同时实现了AutowireCapableBeanFactory ,也拥有了自动注入的功能

2.2.2 实现了属性赋值和组件注入

Provides bean creation (with constructor resolution), property population, wiring (including autowiring), and initialization. Handles runtime bean references, resolves managed collections, calls initialization methods, etc. Supports autowiring constructors, properties by name, and properties by type. 提供bean创建(通过构造函数解析)、属性填充、连接(包括自动装配)和初始化。处理运行时bean引用、解析托管集合、调用初始化方法等。支持自动装配构造函数、按名称的属性和按类型的属性。

2.2.3 保留模板方法

The main template method to be implemented by subclasses is AutowireCapableBeanFactory.resolveDependency(DependencyDescriptor, String, Set, TypeConverter), used for autowiring by type. In case of a factory which is capable of searching its bean definitions, matching beans will typically be implemented through such a search. For other factory styles, simplified matching algorithms can be implemented.

子类要实现的主要模板方法是AutowireCapableBeanFactory。resolveDependency(DependencyDescriptor, String, Set, TypeConverter),用于按类型自动装配。对于能够搜索其bean定义的工厂,匹配的bean通常通过这样的搜索来实现。对于其他工厂样式,可以实现简化的匹配算法。

resolveDependency 这个模板方法没有被实现,它是用来解析 Bean 成员中的一些属性依赖关系的。

2.2.4 不负责 BeanDefinition 注册

Note that this class does not assume or implement bean definition registry capabilities. See DefaultListableBeanFactory for an implementation of the ListableBeanFactory and BeanDefinitionRegistry interfaces, which represent the API and SPI view of such a factory, respectively.

请注意,该类不假设或实现bean定义注册表功能。关于ListableBeanFactory和BeanDefinitionRegistry接口的实现,请参阅DefaultListableBeanFactory,它们分别表示这样一个工厂的API和SPI视图。

这段的意思是,它只实现了对 Bean 的创建、赋值、注入、初始化。但是 Bean 是如何流转到 BeanFactory 的,它并不关心,例如 Bean 的创建和进入会在后面 BeanDefinition 和 Bean 的生命周期中解释。

2.3 DefaultListableBeanFactory

地址:DefaultListableBeanFactory

2.3.1 最终的默认实现

Spring’s default implementation of the ConfigurableListableBeanFactory and BeanDefinitionRegistry interfaces: a full-fledged bean factory based on bean definition metadata, extensible through post-processors.

Spring对ConfigurableListableBeanFactory和BeanDefinitionRegistry接口的默认实现:一个基于bean定义元数据的成熟的bean工厂,可以通过后处理器进行扩展。

第一段主要是指出了它的地位,它现在是唯一的一个默认的成熟实现。 BeanDefinitionRegistry 后面再提。

2.3.2 注册 bean 定义信息再注入 bean

Typical usage is registering all bean definitions first (possibly read from a bean definition file), before accessing beans. Bean lookup by name is therefore an inexpensive operation in a local bean definition table, operating on pre-resolved bean definition metadata objects.

典型的用法是在访问bean之前,首先注册所有bean定义(可能是从bean定义文件中读取)。因此,按名称查找Bean是本地Bean定义表中的一种成本较低的操作,它对预先解析的Bean定义元数据对象进行操作。

DefaultListableBeanFactory 实现了注册 bean 定义信息的行为,这个就是通过 BeanDefinitionRegistry 实现的,这个具体的流程会在 bean 的生命周期的时候提到。

2.3.3 不解析 bean 定义文件

Note that readers for specific bean definition formats are typically implemented separately rather than as bean factory subclasses: see for example XmlBeanDefinitionReader.

请注意,特定bean定义格式的读取器通常是单独实现的,而不是作为bean工厂的子类:例如,请参阅XmlBeanDefinitionReader。

这一段能体现出 Spring 对于单一职责的把控。

2.3.4 它的替代实现

For an alternative implementation of the ListableBeanFactory interface, have a look at StaticListableBeanFactory, which manages existing bean instances rather than creating new ones based on bean definitions.

对于ListableBeanFactory接口的另一种实现,请查看StaticListableBeanFactory,它管理现有的bean实例,而不是根据bean定义创建新的实例。

StaticListableBeanFactory 这个实现比较简单,也基本不会去用。

2.4 XmlBeanFactory

地址:XmlBeanFactory
在 Spring 3.1 后,XmlBeanFactory 已经过时了,后来使用了 DefaultListableBeanFactory 配合 XmlBeanDefinitionReader,这样更加满足组价你的单一职责原则。