SpringBoot源码解读与原理分析(七)BeanFactory

文章目录

  • 3 SpringBoot的IOC容器
    • 3.1 SpringFramework的IOC容器
      • 3.1.1 BeanFactory
        • 3.1.1.1 BeanFactory根接口
        • 3.1.1.2 HierarchicalBeanFactory
        • 3.1.1.3 ListableBeanFactory
        • 3.1.1.4 AutowireCapableBeanFactory
        • 3.1.1.5 ConfigurableBeanFactory
        • 3.1.1.6 AbstractBeanFactory
        • 3.1.1.7 AbstractAutowireCapableBeanFactory
        • 3.1.1.8 DefaultListableBeanFactory
        • 3.1.1.9 总结

3 SpringBoot的IOC容器

第2章梳理的是SpringBoot的自动装配机制,无论是原生的装配,还是自动装配,最终组件都会装配到IOC容器中。
第3章梳理SpringFramework的IOC容器设计,以及SpringBoot对其的利用与拓展。

3.1 SpringFramework的IOC容器

关于SpringFramework的IOC容器,我们首先想到的应该是ApplicationContext或者BeanFactory。在SpringFramework的官方文档中,有一个片段解释了ApplicationContext和BeanFactory的关系。

The org.springframework.beansand org.springframework.contextpackages are the basis for Spring Framework’s IoC container. The BeanFactoryinterface provides an advanced configuration mechanism capable of managing any type of object. ApplicationContextis a sub-interface of BeanFactory. 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 WebApplicationContextfor 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及其派生接口的继承结构,如图:

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 as ListableBeanFactoryand org.springframework.beans.factory.config.ConfigurableBeanFactoryare 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.beanspackage 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 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.

第六段:描述了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:
  • postProcessBeforeDestructionmethods 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 setParentBeanFactorymethod for bean factories that allow setting the parent in a configurable fashion can be found in the ConfigurableBeanFactoryinterface.

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 BeanFactoryinterface 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. BeanFactoryimplementations 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 the BeanFactoryUtilshelper 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);// 手动注册一个单实例DogbeanFactory.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.BeanFactoryinterface 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.BeanFactoryor org.springframework.beans.factory.ListableBeanFactoryfor 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.ApplicationContextfacades, as it is hardly ever used by application code. That said, it is available from an application context too, accessible through ApplicationContext’s org.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.BeanFactoryinterface.

第一段:这是大多数BeanFactory都要实现的配置接口。它提供配置BeanFactory的工具,以及BeanFactory接口中的客户端方法。

This bean factory interface is not meant to be used in normal application code: Stick to org.springframework.beans.factory.BeanFactoryor org.springframework.beans.factory.ListableBeanFactoryfor 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.BeanFactoryimplementations, providing the full capabilities of the org.springframework.beans.factory.config.ConfigurableBeanFactorySPI. 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.FactoryBeanhandling, aliases, bean definition merging for child bean definitions, and bean destruction (org.springframework.beans.factory.DisposableBeaninterface, custom destroy methods). Furthermore, it can manage a bean factory hierarchy (delegating to the parent in case of an unknown bean), through implementing the org.springframework.beans.factory.HierarchicalBeanFactoryinterface.

第二段:AbstractBeanFactory可以提供一个单实例缓存(通过它的父类DefaultSingletonBeanRegistry)、单例/原型Bean的裁定、FactoryBean处理、别名存储、用于子Bean定义的Bean定义合并,以及Bean销毁(用DisposableBean接口或自定义的destroy方法)。此外,AbstractBeanFactory可以通过实现HierarchicalBeanFactory接口来管理BeanFactory的层次性结构(在未知Bean的情况下委托给父级工厂)。

The main template methods to be implemented by subclasses are getBeanDefinitionand createBean, 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 DefaultListableBeanFactoryand AbstractAutowireCapableBeanFactory.

第三段:由子类实现的主要模板方法是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 RootBeanDefinitionclass. Implements the org.springframework.beans.factory.config.AutowireCapableBeanFactoryinterface in addition to AbstractBeanFactory’s createBeanmethod.

第一段: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 DefaultListableBeanFactoryfor an implementation of the org.springframework.beans.factory.ListableBeanFactoryand BeanDefinitionRegistryinterfaces, 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 ConfigurableListableBeanFactoryand BeanDefinitionRegistryinterfaces: 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.ListableBeanFactoryinterface, have a look at StaticListableBeanFactory, 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及其子接口
BeanFactory是一个统一管理Bean组件的容器,它的核心工作是控制Bean在创建阶段的声明周期与bean对象的统一管理,而对于Bean从哪里来、如何被创建、有哪些依赖要注入、这些都与BeanFactory无关,而是有专门的组件来处理。

  • HierarchicalBeanFactory :BeanFactory的层次性
  • ListableBeanFactory :可列举Bean
  • AutowireCapableBeanFactory :自动注入一些现有的、没有被SpringFramework统一管理的Bean
  • ConfigurableBeanFactory :对BeanFactory进行修改、扩展
  • AbstractBeanFactory :对getBeanDefinition和createBean方法做了规范定义
  • AbstractAutowireCapableBeanFactory :对Bean的创建、赋值、注入和初始化的逻辑
  • DefaultListableBeanFactory :注册Bean定义信息

本节完,更多内容请查阅分类专栏:SpringBoot源码解读与原理分析

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2774373.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习之指数分布

指数分布&#xff1a; 指数分布可以用来表示独立随机事件发生的时间间隔。如果一个随机变量X的概率密度函数满足以下形式&#xff0c;就称X服从参数λ的指数分布&#xff0c;记作X ~ E(λ)或X~Exp&#xff08;λ&#xff09;。指数分布只有一个指数参数&#xff0c;且λ>0&a…

SolidWorks学习笔记——入门知识2

目录 建出第一个模型 1、建立草图 2、选取中心线 3、草图绘制 4、拉伸 特征的显示与隐藏 改变特征名称 5、外观 6、渲染 建出第一个模型 1、建立草图 图1 建立草图 按需要选择基准面。 2、选取中心线 图2 选取中心线 3、草图绘制 以对称图形举例&#xff0c;先画出…

【GAMES101】Lecture 18 高级光线传播

这节课不涉及数学原理&#xff0c;只讲流程操作&#xff0c;大家当听这个十万个为什么就行 目录 高级光线传播 无偏光线传播方法 双向路径追踪&#xff08;Bidirectional path tracing) Metropolis light transport (MLT) 有偏光线传播方法 光子映射&#xff08;Photon …

FXTM富拓监管变更!2024开年连续3家交易商注销牌照

交易商的监管信息是经常发生变更的&#xff0c;即使第一次投资时查询平台监管牌照&#xff0c;投资者仍需持续关注其监管动态。千万不要以为第一步审核好后就万事大吉了&#xff01; 2024年开年&#xff0c;就有3家交易商的重要信息发生变更&#xff0c;注销其金融监管牌照&…

按键扫描16Hz-单片机通用模板

按键扫描16Hz-单片机通用模板 一、按键扫描的原理1、直接检测高低电平类型2、矩阵扫描类型3、ADC检测类型二、---.c的实现1、void keyScan(void) 按键扫描函数①void FHiKey(void) 按键按下功能②void FSameKey(void) 按键长按功能③void FLowKey(void) 按键释放功能三、key.h的…

Leetcode—135. 分发糖果【中等】

2024每日刷题&#xff08;113&#xff09; Leetcode—135. 分发糖果 算法思想 这里可以利用贪心策略&#xff0c;求局部最优解&#xff0c;然后合并为全局最优解。具体来说&#xff0c;将原问题中相邻孩子的条件划分为左相邻孩子和右相邻孩子两个条件&#xff0c;依次求解出两…

Phobos捆绑某数控软件AdobeIPCBroker组件定向勒索

前言 Phobos勒索病毒最早于2019年被首次发现并开始流行起来&#xff0c;该勒索病毒的勒索提示信息特征与CrySiS(Dharma)勒索病毒非常相似&#xff0c;但是两款勒索病毒的代码特征却是完全不一样&#xff0c;近日笔者在逛某开源恶意软件沙箱的时候发现了一款Phobos勒索病毒捆绑…

应用层DoS

应用层&#xff08;application layer&#xff09;是七层OSI模型的第七层。应用层直接和应用程序 对接并提供常见的网络应用服务&#xff0c;能够在实现多个系统应用进程相互通信的同 时&#xff0c;完成一系列业务处理所需的服务。位于应用层的协议有很多&#xff0c;常见的包…

【已解决】:pip is configured with locations that require TLS/SSL

在使用pip进行软件包安装的时候出现问题&#xff1a; WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. 解决&#xff1a; mkdir -p ~/.pip vim ~/.pip/pip.conf然后输入内容&#xff1a; [global] ind…

07-OpenFeign-HTTP压缩优化

gzip是一种数据格式&#xff0c;采用用deflate算法压缩数据&#xff1b;gzip是一种流行的数据压缩算法&#xff0c;应用十分广泛&#xff0c;尤其是在Linux平台。 当GZIP压缩到一个纯文本数据时&#xff0c;效果是非常明显的&#xff0c;大约可以减少70&#xff05;以上的数据…

第九个知识点:内部对象

Date对象: <script>var date new Date();date.getFullYear();//年date.getMonth();//月date.getDate();//日date.getDay();//星期几date.getHours();//时date.getMinutes();//分date.getSeconds();//秒date.getTime();//获取时间戳&#xff0c;时间戳时全球统一&#x…

C++力扣题目494--目标和 474--一和零

494.目标和 力扣题目链接(opens new window) 难度&#xff1a;中等 给定一个非负整数数组&#xff0c;a1, a2, ..., an, 和一个目标数&#xff0c;S。现在你有两个符号 和 -。对于数组中的任意一个整数&#xff0c;你都可以从 或 -中选择一个符号添加在前面。 返回可以使…

Backtrader 文档学习- Plotting

Backtrader 文档学习- Plotting 虽然回测是一个基于数学计算的自动化过程&#xff0c;还是希望实际通过可视化验证。无论是使用现有算法回测&#xff0c;还是观察数据驱动的指标&#xff08;内置或自定义&#xff09;。 凡事都要有人完成&#xff0c;绘制数据加载、指标、操作…

PostgreSql与Postgis安装

POstgresql安装 1.登录官网 PostgreSQL: Linux downloads (Red Hat family) 2.选择版本 3.安装 ### 源 yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm ### 客户端 yum install postgresql14 ###…

Java面向对象 继承

目录 继承继承的好处继承具有传递性实例创建Person类Student继承Person类测试 继承 Java中的继承是面向对象编程的一个核心特性&#xff0c;它允许一个类&#xff08;子类或派生类&#xff09;继承另一个类&#xff08;父类或基类&#xff09;的属性和方法。通过继承&#xff0…

【HarmonyOS应用开发】HTTP数据请求(十四)

文章末尾含相关内容源代码 一、概述 日常生活中我们使用应用程序看新闻、发送消息等&#xff0c;都需要连接到互联网&#xff0c;从服务端获取数据。例如&#xff0c;新闻应用可以从新闻服务器中获取最新的热点新闻&#xff0c;从而给用户打造更加丰富、更加实用的体验。 那么…

【Spring】GoF 之工厂模式

一、GoF 23 设计模式简介 设计模式&#xff1a;一种可以被重复利用的解决方案 GoF&#xff08;Gang of Four&#xff09;&#xff0c;中文名——四人组 《Design Patterns: Elements of Reusable Object-Oriented Software》&#xff08;即《设计模式》一书&#xff09;&…

JavaEE作业-实验三

目录 1 实验内容 2 实验要求 3 思路 4 核心代码 5 实验结果 1 实验内容 简单的线上图书交易系统的web层 2 实验要求 ①采用SpringMVC框架&#xff0c;采用REST风格 ②要求具有如下功能&#xff1a;商品分类、订单、购物车、库存 ③独立完成&#xff0c;编写实验报告 …

Unity2D 学习笔记 0.Unity需要记住的常用知识

Unity2D 学习笔记 0.Unity需要记住的常用知识 前言调整Project SettingTilemap相关&#xff08;创建地图块&#xff09;C#脚本相关程序运行函数private void Awake()void Start()void Update() Collider2D碰撞检测private void OnTriggerStay2D(Collider2D player)private void…

猫头虎分享已解决Bug || docker: Error response from daemon: network not found

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通鸿蒙》 …