3 SpringBoot的IOC容器
第2章梳理的是SpringBoot的自动装配机制,无论是原生的装配,还是自动装配,最终组件都会装配到IOC容器中。
第3章梳理SpringFramework的IOC容器设计,以及SpringBoot对其的利用与拓展。
3.1 SpringFramework的IOC容器
关于SpringFramework的IOC容器,我们首先想到的应该是ApplicationContext或者BeanFactory。在SpringFramework的官方文档中,有一个片段解释了ApplicationContext和BeanFactory的关系。
The
org.springframework.beans
andorg.springframework.context
packages are the basis for Spring Framework’s IoC container. TheBeanFactory
interface provides an advanced configuration mechanism capable of managing any type of object.ApplicationContext
is a sub-interface ofBeanFactory
. It adds:
- Easier integration with Spring’s AOP features
- Message resource handling (for use in internationalization)
- Event publication
- Application-layer specific contexts such as the
WebApplicationContext
for use in web applications.
意思是,SpringFramework的org.springframework.beans和org.springframework.context包是IOC容器的基础。BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象。ApplicationContext是BeanFactory的子接口,它增加以下几个特性:
- 与SpringFramework的AOP功能轻松集成;
- 消息资源处理(用于国际化);
- 事件发布;
- 应用层特定的上下文,例如Web应用程序中使用的WebApplicationContext。
总结:BeanFactory是IOC容器的基础抽象,ApplicationContext包含BeanFactory的所有功能,且扩展了更多实用特性。
3.1.1 BeanFactory
BeanFactory是IOC容器的顶层抽象,它仅定义最基础的bean对象的管理。借助IDEA可以生成BeanFactory及其派生接口的继承结构,如图:
3.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 asListableBeanFactory
andorg.springframework.beans.factory.config.ConfigurableBeanFactory
are available for specific purposes.
第一段:描述了BeanFactory是一个根接口。
BeanFactory是一个访问SpringFramework的Bean容器的根接口。这是Bean容器的基本客户端视图;扩展的接口(例如ListableBeanFactory和org.springframework.beans.factory.config.ConfigurableBeanFactory)都是为了实现某些额外的特性。
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).
第二段:描述了BeanFactory中定义的作用域概念。
BeanFactory接口由多个对象实现,这些对象包含多个bean定义(即BeanDefinition),而每一项定义信息均由字符串类型的name进行唯一标识。根据bean对象的定义信息,SpringFramework的工厂会返回一个包含对象的独立实例(原型设计模式),或者返回一个单个共享示例(单例设计模式的一个更高级的替代方法,其中实例是工厂作用域中的单例)。返回bean对象的实例类型取决于bean对象工厂的配置:API是相同的。自SpringFramework2.0以后,根据具体的ApplicationContext可以使用更多的作用域(例如Web环境中的"request"和"session"作用域)。
从这一段的描述可以发现,Bean容器中的实例要么是单例bean,要么是原型bean。返回的实例类型取决于Bean对象工厂的配置:API是相同的。怎么理解“API是相同的”?
在定义Bean的时候,使用@Scope注解来定义作用域:
@Component
@Scope("prototype") // 或者 singleton
public class Person {
@Bean
@Scope("singleton")
public Person a() {
return new Person();
}
}
上面两种方式注入Bean,显式声明作用域,都是用@Scope。意思就是,产生单例Bean和原型Bean所用的API是相同的,都是用@Scope注解来声明,然后由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与环境配置的继承。
这种方法的要点在于,BeanFactory是应用程序组件的注册中心,并集中应用程序组件的配置(例如,单个对象不再需要读取属性文件)。
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.
第四段:描述了SpringFramework在IOC的两种实现上的权衡:推荐使用依赖注入(DI),尽可能避免依赖查找(DL)。
通常最好使用依赖注入(“推”的配置),通过setter方法或构造方法注入的方式配置应用程序对象,而不是用任何形式的“拉”的配置,例如借助BeanFactory进行依赖查找。SpringFramework的依赖注入特性是使用BeanFactory接口及其子接口实现的。
依赖注入的思想是“推”,主张把组件所需的依赖“推”到组件的成员上;
依赖查找的思想是“拉”,组件需要哪些依赖需要组件自己去IOC容器中“拉取”。
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支持多种类型的Bean配置源。
通常,BeanFactory会加载存储在配置源(例如XML配置文件)中的Bean定义,并使用org.springframework.beans包中的API来配置Bean。然而,BeanFactory的实现可以根据需要直接在Java代码中返回它创建的Java对象。Bean定义的存储方式没有任何限制,它可以是LDAP(轻型目录访问协议)、RDBMS(关系型数据库系统)、XML、properties文件等。鼓励的实现方式是支持Bean之间的引用(依赖注入)。
注意,LDAP, RDBMS并不常用,常用的方式包括XML配置文件、注解配置类、模式注解+组件扫描。
In contrast to the methods in
ListableBeanFactory
, all of the operations in this interface will also check parent factories if this is aHierarchicalBeanFactory
. 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.
第六段:描述了BeanFactory可实现层次性。
与ListableBeanFactory中的方法相比,BeanFactory中的所有操作还将检查父级工厂(BeanFactory本身可以支持父子结构,这个父子结构的概念和实现由HierarchicalBeanFactory完成)。如果在BeanFactory实例中没有找到指定的bean对象,则会在父工厂中搜索查找。BeanFactory实例中的Bean应该覆盖任何父工厂中的同名Bean。
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:
- BeanNameAware’s
setBeanName
- BeanClassLoaderAware’s
setBeanClassLoader
…
On shutdown of a bean factory, the following lifecycle methods apply:postProcessBeforeDestruction
methods of DestructionAwareBeanPostProcessors- DisposableBean’s
destroy
- a custom destroy-method definition
第七段:描述了BeanFactory设有完整的生命周期控制机制。
BeanFactory接口实现了尽可能支持标准Bean的生命周期接口。初始化方法的完整集合及其标准顺序为:
- BeanNameAware接口的setBeanName方法
- BeanClassLoaderAware接口的setBeanClassLoader方法
- …
在关闭BeanFactory时,应用以下生命周期方法:
- DestructionAwareBeanPostProcessors的postProcessBeforeDestruction方法
- DisposableBean的destroy方法
- 自定义的destroy方法
总结:BeanFactory的基础特性包括:
- 最基本的根接口容器
- 定义了作用域的概念;
- 推荐使用依赖注入,尽可能避免以来查找;
- 支持多种类型的配置源;
- 层次性设计;
- 完成的生命周期控制机制。
3.1.1.2 HierarchicalBeanFactory
HierarchicalBeanFactory是一个体现了层次性的BeanFactory。
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 theConfigurableBeanFactory
interface.
HierarchicalBeanFactory是BeanFactory的子接口,实现了这个接口的IOC容器具有层次性。可以在ConfigurableBeanFactory接口中找到允许以可配置方式设置父节点的Bean工厂的相应方法setParentBeanFactory。
当调用BeanFactory的getBean方法时,如果这个BeanFactory是具有层次性的Bean,getBean方法会从当前BeanFactory开始查找是否存在指定的Bean,如果找不到就依次向上查找父级BeanFactory,直到找到为止返回,或者最终找不到而抛出NoSuchBeanDefinitionException。
如果当前BeanFactory有指定的Bean,父级BeanFactory也可能还有Bean。因为即便存在父子关系,它们本质上也是不同的容器。因此有可能找到多个相同的Bean。换言之,@Scope中声明singleton只是在单独某一个容器中是单实例的,但有了层次性结构后,对于整体的多个容器就不是单实例的了。
3.1.1.3 ListableBeanFactory
ListableBeanFactory是一个可列举的BeanFactory。实现了ListableBeanFactory的IOC容器,可以将容器中所有的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.
第一段:ListableBeanFactory是BeanFactory接口的扩展实现,它可以枚举所有的Bean实例,而不是向客户端请求那样逐个按名称进行Bean查找。预加载所有Bean定义(例如基于XML的工厂)的BeanFactory实现类可以实现这个接口。
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 theBeanFactoryUtils
helper class to consider beans in ancestor factories too.
第二段:如果当前BeanFactory同时也是一个HierarchicalBeanFactory,则返回值将不考虑任何BeanFactory的层次结构,而只与当前工厂中定义的Bean有关。使用BeanFactoryUtils工具类也可以获取祖先工厂中的bean。
也就是说,ListableBeanFactory只会列举当前容器中的bean对象,而不会列举父级容器中的bean对象。如果想要获取,可以使用BeanFactoryUtils工具类。
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
org.springframework.beans.factory.config.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.
第三段:ListableBeanFactory接口的方法将仅遵循当前工厂的Bean定义,它们会忽略通过其他方式(例如ConfigurableBeanFactory的registerSingleton方法)注册的任何单实例Bean,但getBeanNamesForType和getBeansOfType除外,它们也会检查这种手动注册的单实例Bean。当然,BeanFactory的getBean也允许对这种特殊bean进行特殊访问。然而,在典型的场景中,所有bean将由外部Bean定义进行定义,因此大多数应用程序不需要担心这种差异。
本段强调了ListableBeanFactory会有选择性地列举容器内的bean,有些bean对象在列举期间会被忽略。为什么要这样设计呢?来看一个例子:
(1)定义两个简单类:猫和狗
public class Cat {}
public class Dog {}
(2)编写XML文件将Cat注册到IOC容器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="com.star.springboot.test02.Cat"/>
</beans>
(3)使用XML配置文件加载ListableBeanFactory
public class ListableBeanFactoryApp {
public static void main(String[] args) {
ClassPathResource resource = new ClassPathResource("listable.xml");
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.loadBeanDefinitions(resource);
System.out.println("加载XML文件后容器中的Bean如下:");
Stream.of(beanFactory.getBeanDefinitionNames()).forEach(System.out::println);
}
}
输出结果显示,只有一个Cat对象:
加载XML文件后容器中的Bean如下:
com.star.springboot.test02.Cat#0
(4)手动注册一个单实例Dog
public class ListableBeanFactoryApp {
public static void main(String[] args) {
ClassPathResource resource = new ClassPathResource("listable.xml");
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.loadBeanDefinitions(resource);
System.out.println("加载XML文件后容器中的Bean如下:");
Stream.of(beanFactory.getBeanDefinitionNames()).forEach(System.out::println);
// 手动注册一个单实例Dog
beanFactory.registerSingleton("doggggg", new Dog());
// 再次打印
System.out.println("手动注册单实例Bean后容器中的Bean如下:");
Stream.of(beanFactory.getBeanDefinitionNames()).forEach(System.out::println);
}
}
输出结果显示,依旧只有一个Cat对象:
加载XML文件后容器中的Bean如下:
com.star.springboot.test02.Cat#0
手动注册单实例Bean后容器中的Bean如下:
com.star.springboot.test02.Cat#0
(5)分析
这个结果似乎和预期不符,但印证了javadoc中的说明:ListableBeanFactory在获取容器内的所有bean对象时,不会把手动注册(即使用registerSingleton方法)的bean对象取出。
但容器中肯定是有Dog对象的,通过getBean方法就可以获取:
Dog dog = beanFactory.getBean(Dog.class);
System.out.println("通过getBean方法获取Dog结果:" + dog);
输出结果:
通过getBean方法获取Dog结果:com.star.springboot.test02.Dog@1efbd816
那SpringFramework这样设计的目的是什么?查看AbstractApplicationContext中prepareBeanFactory方法,可以发现使用了registerSingleton:
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
此处使用registerSingleton方法注册了几个仅供SpringFramework内部使用的默认组件。
由此可以看出,这样设计的目的就是为了隐藏这些内部组件,而不希望开发者直接操作它们。
类似于Windows操作系统中的“隐藏受保护的操作系统文件”,这些文件用户默认是看不见的,避免用户误删。
3.1.1.4 AutowireCapableBeanFactory
AutowireCapableBeanFactory直译过来是“具有自动装配能力的BeanFactory”。可见AutowireCapableBeanFactory支持自动注入或依赖注入。
Extension of the
org.springframework.beans.factory.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.
第一段:AutowireCapableBeanFactory是BeanFactory接口的扩展,由能够进行自动注入的Bean工厂实现,前提是它们希望为现有的bean实例暴露此功能。
This subinterface of BeanFactory is not meant to be used in normal application code: stick to
org.springframework.beans.factory.BeanFactory
ororg.springframework.beans.factory.ListableBeanFactory
for typical use cases.
第二段:BeanFactory的这个子接口并不是用在普通的应用程序代码中的,而是在BeanFactory或者ListableBeanFactory中用于典型用例。
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.
第三段:其他框架的集成代码可以利用这个接口来连接和填充SpringFramework无法控制生命周期的现有bean实例。例如,这对于WebWork动作和Tapestry页面对象特别有用。
直接阅读上面三段javadoc还是挺费解的,它要表达的意思是:
AutowireCapableBeanFactory支持组件的自动注入,可以为一些现有的、没有被SpringFramework统一管理的Bean提供组件自动注入的支持。一般在正常的项目开发中不会用到AutowireCapableBeanFactory,而是在第三方框架与SpringFramework整合时才可能会用到。如果第三方框架的某些bean实例无法让SpringFramework接管,但又需要注入一些由SpringFramework管理的bean对象,就可以使用AutowireCapableBeanFactory辅助完成注入。
Note that this interface is not implemented by
org.springframework.context.ApplicationContext
facades, as it is hardly ever used by application code. That said, it is available from an application context too, accessible through ApplicationContext’sorg.springframework.context.ApplicationContext#getAutowireCapableBeanFactory()
method.
注意,ApplicationContext没有实现AutowireCapableBeanFactory接口,因为它几乎不被应用程序代码所使用。也就是说,它可以从应用程序上下文中获取到,通过ApplicationContext的getAutowireCapableBeanFactory方法访问。
总结:AutowireCapableBeanFactory在正常的项目开发中一般不会使用,不需要我们去操作。但如果需要获取AutowireCapableBeanFactory,可以通过ApplicationContext间接获取。
3.1.1.5 ConfigurableBeanFactory
SpringFramework对于核心API的命名有非常强的规律性。当类名中带有 Configurable 前缀时,意味着这个接口的行为有“写”的动作,而去掉 Configurable 前缀的接口只有“读”的动作。
- 可读:一个类的属性设置为private后,提供get方法
- 可写:一个类的属性设置为private后,提供set方法
SpringFramework中,普通的BeanFactory只有get相关操作,而 Configurable 前缀的BeanFactory或者ApplicationContext具有set相关操作。
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
org.springframework.beans.factory.BeanFactory
interface.
第一段:这是大多数BeanFactory都要实现的配置接口。它提供配置BeanFactory的工具,以及BeanFactory接口中的客户端方法。
This bean factory interface is not meant to be used in normal application code: Stick to
org.springframework.beans.factory.BeanFactory
ororg.springframework.beans.factory.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.
第二段:这个接口并不是用在普通的应用程序代码中的,而是在BeanFactory或者ListableBeanFactory中用于典型用例。这个扩展的接口只是为了支持内部的即插即用,以及对BeanFactory配置方法的特殊访问。
总结:ConfigurableBeanFactory提供了配置功能,可以对BeanFactory进行修改、扩展。但官方不希望开发者使用这个接口,因为原则上程序在运行期间不应该对BeanFactory再进行频繁的变动,只应该有读的动作(除非确定要写且有把握,才写)。
3.1.1.6 AbstractBeanFactory
AbstractBeanFactory是BeanFactory最基础的抽象实现,只具有部分功能。
Abstract base class for
org.springframework.beans.factory.BeanFactory
implementations, providing the full capabilities of theorg.springframework.beans.factory.config.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).
第一段:AbstractBeanFactory是BeanFactory接口的抽象基类,提供了ConfigurableBeanFactory类SPI的全部能力。可以被用作从某些后端资源获取Bean定义的基类。
This class provides a singleton cache (through its base class
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
), singleton/prototype determination,org.springframework.beans.factory.FactoryBean
handling, aliases, bean definition merging for child bean definitions, and bean destruction (org.springframework.beans.factory.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 theorg.springframework.beans.factory.HierarchicalBeanFactory
interface.
第二段:AbstractBeanFactory可以提供一个单实例缓存(通过它的父类DefaultSingletonBeanRegistry)、单例/原型Bean的裁定、FactoryBean处理、别名存储、用于子Bean定义的Bean定义合并,以及Bean销毁(用DisposableBean接口或自定义的destroy方法)。此外,AbstractBeanFactory可以通过实现HierarchicalBeanFactory接口来管理BeanFactory的层次性结构(在未知Bean的情况下委托给父级工厂)。
The main template methods to be implemented by subclasses are
getBeanDefinition
andcreateBean
, 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 inDefaultListableBeanFactory
andAbstractAutowireCapableBeanFactory
.
第三段:由子类实现的主要模板方法是getBeanDefinition和createBean,分别代表根据给定的Bean名称获取Bean定义,和根据给定的Bean定义创建Bean对象。这些操作的默认实现可以在DefaultListableBeanFactory和AbstractAutowireCapableBeanFactory中找到。
总结:AbstractBeanFactory是BeanFactory接口的抽象基类,具有一些基础功能,使用模板方法模式对getBeanDefinition和createBean方法做了规范定义。
3.1.1.7 AbstractAutowireCapableBeanFactory
Abstract bean factory superclass that implements default bean creation, with the full capabilities specified by the
RootBeanDefinition
class. Implements theorg.springframework.beans.factory.config.AutowireCapableBeanFactory
interface in addition to AbstractBeanFactory’screateBean
method.
第一段:AbstractAutowireCapableBeanFactory是实现了默认的bean对象创建逻辑的BeanFactory接口的抽象类,具有RootBeanDefinition类指定的完整功能。它除了实现AbstractBeanFactory的createBean方法,还额外实现了AutowireCapableBeanFactory接口的方法。
也就是说,bean对象的创建动作都在AbstractAutowireCapableBeanFactory中完成。
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.
第二段:AbstractAutowireCapableBeanFactory的核心功能包括:bean对象的创建(带有构造函数解析)、属性赋值、依赖注入(包括自动注入)、以及初始化。处理运行时Bean引用,解析托管集合,调用初始化方法等。支持自动装配构造函数,按名称设置属性和按类型设置属性。
The main template method to be implemented by subclasses is
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.
第三段:AbstractAutowireCapableBeanFactory实现的主要的模板方法是resolveDependency,用于根据类型进行自动注入。对于能够获取其Bean定义信息的BeanFactory,通常通过这种查询来实现。对于其他样式的BeanFactory,可以实现简化的匹配算法。
Note that this class does not assume or implement bean definition registry capabilities. See
DefaultListableBeanFactory
for an implementation of theorg.springframework.beans.factory.ListableBeanFactory
andBeanDefinitionRegistry
interfaces, which represent the API and SPI view of such a factory, respectively.
第四段:注意,AbstractAutowireCapableBeanFactory没有假定或实现Bean定义信息注册的能力。请参阅DefaultListableBeanFactory获取ListableBeanFactory和BeanDefinitionRegistry接口的实现,它们分别代表了这种工厂的API和SPI视图。
总结:AbstractAutowireCapableBeanFactory实现了对Bean的创建、赋值、注入和初始化的逻辑,但对于Bean的定义信息是如何进入BeanFactory的没有涉及。
3.1.1.8 DefaultListableBeanFactory
DefaultListableBeanFactory是唯一目前底层正在使用的BeanFactory的落地实现。
Spring’s default implementation of the
ConfigurableListableBeanFactory
andBeanDefinitionRegistry
interfaces: a full-fledged bean factory based on bean definition metadata, extensible through post-processors.
第一段:DefaultListableBeanFactory是ConfigurableListableBeanFactory和BeanDefinitionRegistry接口的默认实现:一个基于Bean定义信息元数据的成熟的BeanFactory,可以通过后处理器进行拓展。
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定义元数据对象上。
Note that readers for specific bean definition formats are typically implemented separately rather than as bean factory subclasses: see for example
org.springframework.beans.factory.xml.XmlBeanDefinitionReader
.
第三段:注意,特定的Bean定义信息格式的解析器通常是单独实现的,而不是作为BeanFactory的子类,参见XmlBeanDefinitionReader。
For an alternative implementation of the
org.springframework.beans.factory.ListableBeanFactory
interface, have a look atStaticListableBeanFactory
, which manages existing bean instances rather than creating new ones based on bean definitions.
第四段:对于ListableBeanFactory的替代实现,参见StaticListableBeanFactory,这个类管理着现有的bean实例,而不是根据Bean定义信息创建新实例。
总结:DefaultListableBeanFactory的源码中已经没有abstract关键字的标注,说明它是一个成熟的落地实现类,在AbstractAutowireCapableBeanFactory的基础上完成注册Bean定义信息的动作。
3.1.1.9 总结
至此,可以总结一下BeanFactory的功能:
BeanFactory是一个统一管理Bean组件的容器,它的核心工作是控制Bean在创建阶段的声明周期与bean对象的统一管理,而对于Bean从哪里来、如何被创建、有哪些依赖要注入、这些都与BeanFactory无关,而是有专门的组件来处理。
- HierarchicalBeanFactory :BeanFactory的层次性
- ListableBeanFactory :可列举Bean
- AutowireCapableBeanFactory :自动注入一些现有的、没有被SpringFramework统一管理的Bean
- ConfigurableBeanFactory :对BeanFactory进行修改、扩展
- AbstractBeanFactory :对getBeanDefinition和createBean方法做了规范定义
- AbstractAutowireCapableBeanFactory :对Bean的创建、赋值、注入和初始化的逻辑
- DefaultListableBeanFactory :注册Bean定义信息
本节完,更多内容请查阅分类专栏:SpringBoot源码解读与原理分析