【Java】【系列篇】【Spring源码解析】【三】【体系】【BeanFactory体系】

news2024/11/23 22:17:35

BeanFactory体系

  • BeanFactory整体结构体系图
  • 顶层接口-BeanFactory
    • 1.1、描述
    • 1.2、方法解析(15个)
      • 1.2.1、属性
      • 1.2.2、获取bean实例
      • 1.2.3、获取bean的提供者(对象工厂)
      • 1.2.4、判断是否包含bean
      • 1.2.5、单例,原型,bean类型的判断
      • 1.2.6、获取bean的类型,别名
  • BeanFactory与下级接口接口图
  • 二级接口-ListableBeanFactory
    • 2.1、描述
    • 2.2、方法解析(12个)
      • 2.2.1、获取bean属性
      • 2.2.2、根据bean的类型获取bean名称
      • 2.2.3、根据bean的类型获取bean
      • 2.2.4、查找使用注解的类
      • 2.2.5、查找一个类上的注解
  • 二级接口-HierarchicalBeanFactory
    • 3.1、描述
    • 3.2、方法解析(2个)
  • 二级接口-AutowireCapableBeanFactory
    • 4.1、描述
    • 4.2、方法解析(15个)
      • 4.2.1、属性
      • 4.2.2、粗粒度创建、装配Bean的方法
      • 4.2.3、 用于对bean生命周期进行细粒度控制的专门方法
      • 4.2.4、委托用于解析注入点的方法
  • 三级接口-ConfigurableBeanFactory
    • 5.1、描述
    • 5.2、方法解析(38个)
      • 5.2.1、属性
      • 5.2.2、父工厂设置*
      • 5.2.3、类加载器设置
      • 5.2.4、临时类加载器设置
      • 5.2.5、缓存元数据设置
      • 5.2.6、表达式解析器设置
      • 5.2.7、类型转化器设置
      • 5.2.8、自定义的类型转换器设置
      • 5.2.9、String值解析器设置
      • 5.2.10、Bean创建状态控制设置
      • 5.2.11、属性编辑器
      • 5.2.12、BeanPostProcessor添加*
      • 5.2.13、Scope作用域
      • 5.2.14、别名设置
      • 5.2.15、bean依赖
      • 5.2.16、访问权限控制
      • 5.2.17、拷贝配置信息
      • 5.2.18、合并BeanDefinition*
      • 5.2.19、是否是FactoryBean类型
      • 5.2.20、销毁bean
  • 四级接口-ConfigurableListableBeanFactory
    • 6.1、描述
    • 6.2、方法解析(10个)
      • 6.2.1、设置忽略的依赖关系
      • 6.2.2、注册找到的特殊依赖
      • 6.2.3、判断指定的Bean是否有资格作为自动装配的候选者
      • 6.2.4、获取bean定义 (可以访问属性值跟构造方法的参数值)
      • 6.2.5、清理元数据的缓存
      • 6.2.6、锁定配置信息.在调用refresh时会使用到
      • 6.2.7、预加载不是懒加载的单例.用于解决循环依赖问题
  • 抽象类-AbstractBeanFactory
    • 7.1、描述
    • 7.2、方法分析
      • 7.2.1、属性
      • 7.2.2、BeanFactory接口的实现
      • 7.2.3、HierarchicalBeanFactory接口方法的实现
      • 7.2.4、ConfigurableBeanFactory接口的实现
      • 7.2.5、由子类实现的抽象方法
  • 抽象类-AbstractAutowireCapableBeanFactory
    • 8.1、描述
    • 8.2、方法分析
      • 8.2.1、属性
      • 8.2.2、构造器
      • 8.2.3、创建和装配外部bean实例
      • 8.2.4、用于对bean生命周期进行细粒度控制的专门方法
      • 8.2.5、相关AbstractBeanFactory模板方法的实现
  • 最终类-DefaultListableBeanFactory
    • 9.1、描述
    • 9.2、方法分析
      • 9.2.1、属性
      • 9.2.2、BeanFactory接口的实现
      • 9.2.3、ListableBeanFactory接口的实现
      • 9.2.4、ConfigurableListableBeanFactory接口的实现
      • 9.2.5、BeanDefinitionRegistry接口的实现
      • 9.2.6、依赖性解析功能
      • 9.2.7、序列化支持
  • 引用

本文的主要目的主要是为了对BeanFactory体系里的每个类有个大致的了解,方便更深入的理解Spring源码;你可以当成一个字典来看。
注:在这个体系中,它体现了接口隔离原则--客户端不应该依赖它不需要的接口;类间的依赖关系应该建立在最小的接口上。

BeanFactory整体结构体系图

image-20221229160030727

顶层接口-BeanFactory

1.1、描述

BeanFactory是IOC容器最基础的接口,定义了IOC容器最基本的规范,BeanFactory里只对IOC容器的基本行为作了定义,主要有以下几种功能:
a. 获取bean实例
b. 获取bean的提供者(对象工厂)
c. 判断是否包含bean
d. 单例,原型,bean类型的判断
e. 获取bean的类型,别名
Spring中提供了相对应得很多实现了BeanFactory的模板给我们调用,它的子类扩展实现某些额外的特性,如:层次性(HierarchicalBeanFactory),可搜索性(ListableBeanFactory),可配置性(ConfigurableBeanFactory)等。

1.2、方法解析(15个)

1.2.1、属性

String FACTORY_BEAN_PREFIX = "&";
作用:用于区别FactoryBeanBean。
例如:如果一个名字为myJndiObject的FactoryBean,BeanFactory调用getBean("myJndiObject")方法时返回的不是该FactoryBean实例,而是该FactoryBean调用其自身getObject方法返回的对象,要想返回该FactoryBean实例,则需要BeanFactory实例这样调用getBean("&myJndiObject")

1.2.2、获取bean实例

Object getBean(String name) throws BeansException;
作用:
    1. 通过bean名称获取bean实例,无论是Singleton还是Prototype2. 如果是name是别名,会解析为最终的真实名称。
    3. 如果在本BeanFactory没有找到实例,会从父BeanFactory查找

<T> T getBean(String name, Class<T> requiredType) throws BeansException;
作用:和上面方法并无太大区别,只是提供了一个类型检测,如果找到的bean不是要求的类型,则抛出BeanNotOfRequiredTypeException;
requiredType:返回bean实例的类型,可以是其实现的接口,也可以是其父类,也可以是null任意匹配
异常抛出:
    (1)NoSuchBeanDefinitionException在该实例和其所有父类实例下均找不到指定的bean实例时抛出
    (2)BeanNotOfRequiredTypeException 找到的实例与请求的类型不一样时抛出
    (3)BeansException 指定的实例无法被创建时抛出

Object getBean(String name, Object... args) throws BeansException;
作用:允许清楚的指定普通bean的构造函数的参数列表或者是FactoryBean的工厂方法参数列表,这将会覆盖bean原定义中的默认参数
args:普通Bean的构造函数参数,或者是FactoryBean的工厂方法参数列表

<T> T getBean(Class<T> requiredType) throws BeansException;
作用:
    1. 返回任何惟一匹配 给定类型的bean实例。这个方法进入ListableBeanFactory的 by-type查找区域查找 ,但也可能给定类型的名字被转换成传统的按名字查找。
    2. 针对更多对于beans集合的检索操作,使用ListableBeanFactory,BeanFactoryUtils。指定类型不可以是空。(有点搞不懂,标记此处)
requiredType:指定必须匹配的类型

<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
作用:
    1. 允许清楚的指定普通bean的构造函数的参数列表或者是FactoryBean的工厂方法参数列表,这将会覆盖bean原定义中的默认参数。
    2. 这个方法进入ListableBeanFactory的 by-type查找区域查找 ,但也可能给定类型的名字被转换成传统的按名字查找。针对更多对于beans集合的检索操作,使用ListableBeanFactory,BeanFactoryUtils3. 仅在创建一个新的实例的时候使用,而不是检索已存在实例的时候,需要返回的是新创建的,而不是已存在的。

1.2.3、获取bean的提供者(对象工厂)

<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

返回指定bean的提供程序(Provider),允许延迟(这是重点)按需检索实例,包括可用性和唯一性选项

1.2.4、判断是否包含bean

boolean containsBean(String name);
作用:
* 判断这个BeanFactory是否包含指定名字的bean定义或者是包含指定名字的处部已注册的bean实例。
* 如果所给名字为别名,将会被转换回正确的规范的bean名字。
* 如果当前BeanFactory是分层的,那么当在本实例范围内找不到时会在其所有父工厂实例里查找。
* 如果存在指定名字的bean定义或者是单例实例,返回true,与抽象类还是实现类,延迟加载还是马上加载,当前范围还是其父工厂范围无关。
注意:这个方法返回true,但并不意味着当传入同样名字调用此工厂的getBean方法时一定会获得对象实例。

1.2.5、单例,原型,bean类型的判断

boolean isSingleton(String name) throws NoSuchBeanDefinitionException; // 是否为单例 若是单例,getBean()每次都会返回同一个实例
作用:
* 判断是否是一个共享的单例对象。如果是,查看getBean方法看其是否一定会返回同一实例。
* 注意:此方法返回false,并不表示给定名字的实例一定是独立的实例。
* 它表示非单例实例,也可能是对应一定范围的Bean(request,session)* 将别名转换回对应的规范的bean名字

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;// 是否为原型
作用:
* 判断是否是一个独立的对象,如果是true,如果是,查看getBean方法看其是否一定会返回一个独立的实例。
* 注意:此方法返回false,并不表示给定名字的实例一定是单例实例。
* 它表示非独立的实例,也可能是对应一定范围的Bean(request,session)* 将别名转换回对应的规范的bean名字
* 当在本工厂实例中无法找到给定名字的bean时,在其父工厂中查找

boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;//指定名字的bean是否和指定的类型匹配
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
作用:
1. 检查给定名字的实例是否匹配指定类型。
2. 更具体的说,检查通过给定名字的一个getBean调用返回的对象是否是指定的目录类型。
3. 如果给定名字的bean本工厂内找不到,将到其父工厂中查找

1.2.6、获取bean的类型,别名

@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;// 获取指定名字的bean的类型
@Nullable
Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;
作用:
* 明确给定名字对应Bean的类型。
* 具体说就是,确定通过给定名字调用getBean方法返回的Object的类型。
* 对于FactoryBean,返回FactoryBean创建的Object的类型,就像FactoryBean的getObjectType方法

String[] getAliases(String name);// 获取指定名字的bean的所有别名
作用:
* 通过给定的bean名字,获取其所有的别名。
* 当getBean方法调用时,那些所有的别名都指向同一个bean。
* 如果传入的是一个别名,那么这个别名所对应的bean名字,和这个bean名字所对的其他别名被返回,这个bean的名字在数组的第一位。

BeanFactory与下级接口接口图

image-20221229160347949

二级接口-ListableBeanFactory

2.1、描述

特性:可搜索性

这个工厂接口最大的特点就是可以列出工厂可以生产的所有实例。作为上文指出的BeanFactory二级接口,有9个独有的方法,扩展了跟BeanDefinition的功能,提供了BeanDefinition、BeanName、注解有关的各种操作。它可以根据条件返回Bean的集合,这就是它名字的由来——ListableBeanFactory。

注意点:

  1. 该接口不支持分层结构(对于继承了HierarchicalBeanFactory的BeanFactory来说),也即该接口只能枚举当前facotry的Bean,但是可以通过BeanFactoryUtils工具类来获取那些在父BeanFactory中的Bean
  2. 此接口中的所有方法只会考虑本BeanFactory实例中的Bean定义,除getBeanNamesOfType,getBeansOfType方法外,它们将忽略任何已经通过其他方式(如ConfiguableBeanactory registerSingleton方法)注册的单例bean,这主要也是因为getBean方法可以访问这些手动配置的Bean定义。

功能:

​ a. 获取bean属性
​ b. 根据bean的类型获取bean名称
​ c. 根据bean的类型获取bean
​ d. 查找使用注解的类
​ e. 查找一个类上的注解

官方5.2.x文档翻译:

bean工厂实现的BeanFactory接口的扩展,可以枚举其所有bean实例,而不是按客户端请求逐个按名称尝试bean查找。预加载所有bean定义的BeanFactory实现(例如基于xml的工厂)可以实现此接口。如果这是一个HierarchicalBeanFactory,则返回值将不考虑任何BeanFactory层次结构,而只与当前工厂中定义的bean相关。使用BeanFactoryutils帮助类也可以考虑祖先工厂中的bean。该接口中的方法将只尊重该工厂的bean定义。它们将忽略任何通过其他方式(如ConfigurableBeanFactory的registersingleton方法)注册的单例bean,除了getBeanNames ForType和getBeansofType,这两个方法也会检查手动注册的单例bean。当然,BeanFactory的getBean也允许对这些特殊bean的透明访问。然而,在典型场景中,所有bean都将由外部bean定义定义,因此大多数应用程序不需要担心这种区别。注意:除了getBeanDefinitionCount和containsBeanDefinition之外,此接口中的方法不是为频繁调用而设计的。实现可能很慢。

2.2、方法解析(12个)

2.2.1、获取bean属性

boolean containsBeanDefinition(String beanName);
作用:查看是否包含指定名字的BeanDefinition(里面存放着bean的实例化所需要的信息)
注意点:
    1. 不考虑这个工厂参与的任何层级关系
    2. 忽略父factory和其他factory注册的单例bean(标准:忽略不是bean定义的所有通过其他方式注册的单例bean)(其他:不支持查找非配置文件定义的单例Bean?)

int getBeanDefinitionCount();
作用:查看此BeanFactory中包含的Bean数量
注意点:
    1. 不考虑这个工厂参与的任何层级关系
    2. 忽略父factory和其他factory注册的单例bean(标准:忽略不是bean定义的所有通过其他方式注册的单例bean)(其他:不支持查找非配置文件定义的单例Bean?)

String[] getBeanDefinitionNames();
作用:返回此BeanFactory中所包含的所有Bean定义的名称
注意点:
    1. 不考虑这个工厂参与的任何层级关系
    2. 忽略父factory和其他factory注册的单例bean(标准:忽略不是bean定义的所有通过其他方式注册的单例bean)(其他:不支持查找非配置文件定义的单例Bean?)

2.2.2、根据bean的类型获取bean名称

String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(@Nullable Class<?> type);
作用:返回此BeanFactory中所有指定类型的Bean的名字
注意点:
    1.如果是普通bean,则是bean定义的名字,如果是 FactoryBean,则是其getObjectType方法返回的对象的名字,当提供的类型匹配FactoryBean时返回&BeanName
    2.这个方法只考虑最顶层的bean(top-level beans),内部嵌套的bean(nested beans)即便可能匹配指定的类型也不考虑(不支持内部类)
    3.不考虑这个工厂参与的任何层级关系。也可以使用BeanFactoryUtils的beanNamesForTypeIncludingAncestors方法处理有关继承方面的问题。
    4.不忽略已通过bean定义以外的其他方式注册的单例bean(可以获取手动注册的bean)
    5.此签名的getBeanNamesForType方法会返回所有Scope类型的Bean,在大多数的实现中,其返回结果和其重载方法getBeanNamesForType(type, true, true)返回结果一致。
    6.这个方法返回的bean名称应该尽可能与后台配置的bean定义顺序一样
return:若没有符合条件的,返回的空数组,而不是null

String[] getBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit);
String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
作用:返回此BeanFactory中所有指定类型(或指定类型的子类型)的Bean的名字
注意点:
    1.如果是普通bean,则是bean定义的名字;如果是 FactoryBean,受allowEagerInit的值影响(具体看字段解释)
    2.这个方法只考虑最顶层的bean(top-level beans),内部嵌套的bean(nested beans)即便可能匹配指定的类型也不考虑(不支持内部类)
    3.不考虑这个工厂参与的任何层级关系。也可以使用BeanFactoryUtils的beanNamesForTypeIncludingAncestors方法处理有关继承方面的问题。
    4.不忽略已通过bean定义以外的其他方式注册的单例bean(可以获取手动注册的bean)
    5.此签名的getBeanNamesForType方法会返回所有Scope类型的Bean,在大多数的实现中,其返回结果和其重载方法getBeanNamesForType(type, true, true)返回结果一致。
    6.这个方法返回的bean名称应该尽可能与后台配置的bean定义顺序一样
includeNonSingletons: false表示只查单例Beantrue表示包含prototype或者其它ScopeBean们(也适用于FactoryBean)
allowEagerInit:主要是解决FactoryBean的情况。若为false,只会去检查FactoryBean本身,若为trueFactoryBean本身和它的产生的对象都会被检查匹配

2.2.3、根据bean的类型获取bean

<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
作用:返回匹配给定类型(包含子类)的实例
注意点:
    1.返回匹配给定类型(包含子类)的实例,可能是通过bean定义创建,也可以是FactoryBean时其getObjectType返回
    2.此方法仅考虑最顶层bean,不含其内部嵌套的bean,即使内部嵌套的bean匹配给定类型
    3.如果考虑FactoryBean创建的对象,需要先初始化对应的FactoryBean。如果FactoryBean创建的对象与指定类型不匹配,则需要匹配FactoryBean对象本身
    4.不考虑此工厂所参与的任何层次,也可以使用BeanFactoryUtils的beansOfTypeIncludingAncestors的方法处理考虑分层处理的情况。
    5.忽略已通过bean定义以外的其他方式注册的单例bean(可以获取手动注册的bean);不检测无法实例化的Bean(如抽象Bean)
    6.getBeansOfType方法的这个版本匹配所有种类的bean,可是是单例的,原型的,FactoryBean。在许多实现中,此方法返回的结果与调用getBeansOfType(type, true, true)一样。
type:指定的类或者是接口,如果是空,则匹配所有现有bean
return:这个方法返回的map应该是匹配指定类型的bean的名字与其名字对应的实例的键值对,并且顺序要尽最大可能的与配置时一样。

<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException;
作用:返回匹配给定类型(包含子类)的实例
注意点:
    1.返回匹配给定类型(包含子类)的实例,可能是通过bean定义创建,也可以是FactoryBean时其getObjectType返回
    2.此方法仅考虑最顶层bean,不含其内部嵌套的bean,即使内部嵌套的bean匹配给定类型
    3.考虑FactoryBean创建的对象时:如果设置allowEagerInit,也就是默认初始化FactoryBean.这时如果FactoryBean创建的对象与指定的类型不匹配,将匹配该FactoryBean实例本身。
    4.不考虑此工厂所参与的任何层次,也可以使用BeanFactoryUtils的beansOfTypeIncludingAncestors的方法处理考虑分层处理的情况。
     5.忽略已通过bean定义以外的其他方式注册的单例bean(可以获取手动注册的bean);不检测无法实例化的Bean(如抽象Bean)
includeNonSingletons: false表示只查单例Beantrue表示包含prototype或者其它ScopeBean们(也适用于FactoryBean)
allowEagerInit:主要是解决FactoryBean的情况。若为false,只会去检查FactoryBean本身,若为trueFactoryBean本身和它的产生的对象都会被检查匹配

2.2.4、查找使用注解的类

String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
作用:这个接口会把所有标注有指定注解的Bean的定义信息的BeanName返回

Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
作用:查找所有注解为指定类型的bean,返回一个bean名字与其对应实例的映射表

2.2.5、查找一个类上的注解

@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
        throws NoSuchBeanDefinitionException;
作用:查找指定bean中的所有指定的注解(会考虑它实现的接口和父类中的注解)
注意点:
    1. 如果本类没找到,还会去它的接口、它的父类里面找
    2. getBeanNamesForAnnotation依赖于此接口

二级接口-HierarchicalBeanFactory

3.1、描述

HierarchicalBeanFactory接口定义了BeanFactory之间的分层结构 提供父容器的访问功能。
父子级联loc容器的接口,子容器可以通过接口方法访问父容器;通过HierarchicalBeanFactory接口, Spring的loC容器可以建立父子层级关联的容器体系,子容器可以访问父容器中的Bean,但父容器不能访问子容器的Bean,Spring 使用父子容器实现了很多功能,比如在 Spring MVC 中,展现层 Bean 位于一个子容器中,而业务层和持久层的Bean位于父容器中。这样,展现层Bean就可以引用业务层和持久层的Bean,而业务层和持久层的Bean则看不到展现层的Bean。

3.2、方法解析(2个)

@Nullable
BeanFactory getParentBeanFactory();
作用:返回本Bean工厂的父工厂(至于父工厂怎么设置进去的,却放在了三级接口);这个方法实现了工厂的分层
	
boolean containsLocalBean(String name);
作用:本地工厂是否包含这个Bean(忽略其他所有父工厂)。这也是分层思想的体现。

注意:即便存在父子关系,但它们本质上是不同的容器,所以有可能找到多个相同的Bean;@Scope中声明的Singleton对象只是在一个容器中是单实例的,但有了层次性结构后,对于整体的多个容器就不是单实例的了

二级接口-AutowireCapableBeanFactory

4.1、描述

该接口的作用主要整合第三方框架(框架之外,没有向Spring托管Bean的应用),能让Spring管理的Bean去装配和填充那些不被Spring托管的Bean,使得Spring框架之外的程序具有自动装配等Spring的功能。目前了解到的有两款著名的开源框架JunitQuartz借用了这种机制为自己赋能,达到更好地与Spring契合协作的目的。以微内核 + 插件机制思想,由内核层想办法拿到AutowireCapableBeanFactory,并在构造插件的时候,借助AutowireCapableBeanFactory去为插件赋能,做到无限扩展的可能性。

  1. 正常情况下,不要使用此接口,应该更倾向于使用BeanFactory或者ListableBeanFactory接口。
  2. 需要注意的是,ApplicationContext接口并没有实现此接口,因为应用代码很少用到此功能,如果确实需要的话,可以调用ApplicationContext的getAutowireCapableBeanFactory方法,来获取此接口的实例。
  3. 从宏观上看,AutowireCapableBeanFactory提供了如下能力:
    3.1、为已经实例化的对象装配属性,这些属性对象都是Spring管理的。
    3.2、实例化一个类型,并自动装配,这些属性对象都是Spring管理的,实例化的类可以不被Spring管理(这点特别重要)。
示例:
public class Person {
    //不使用@Autowired
    private User user;
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
}
public void beanTest(){
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
    //ApplicationContext没有实现接口,但是可以通过方法直接获取使用
    AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
    // autowireCapableBeanFactory创建Bean实例,执行多次就创建多个
    Person person = (Person) autowireCapableBeanFactory.createBean(Person.class, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
    //没有@Autowired注解也直接给注入了
    System.out.println("获取自动注入的属性:"+person.getUser());
    //异常: No qualifying bean of type 'com.hou.spring.Person' available
    Person bean = applicationContext.getBean(Person.class);//没有交给spring容器管理
    System.out.println(bean);
}

4.2、方法解析(15个)

4.2.1、属性

用于标识外部自动装配功能是否可用。但是此标识不影响正常的(基于注解的等)自动装配功能的使用

int AUTOWIRE_NO = 0;// 不注入
int AUTOWIRE_BY_NAME = 1; // 根据名称注入
int AUTOWIRE_BY_TYPE = 2;// 根据类型注入
int AUTOWIRE_CONSTRUCTOR = 3;// 根据构造器注入
@Deprecated
int AUTOWIRE_AUTODETECT = 4;// 标识自动识别一种装配策略来实现自动装配(Spring3.0后废弃)
String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";

4.2.2、粗粒度创建、装配Bean的方法

用于创建和填充外部bean实例的典型方法

<T> T createBean(Class<T> beanClass) throws BeansException;
作用:用给定的class创建一个Bean实例,完整经历一个Bean创建过程的生命周期节点回调,但不执行传统的autowiring 
    1.执行此Bean所有的关于Bean生命周期的接口方法如BeanPostProcessor
    2.此方法用于创建一个新实例,它会处理各种带有注解的域和方法,并且会调用所有bean初始化时所需要调用的回调函数
    3.此方法并不意味着by-name或者by-type方式的自动装配,如果需要使用这写功能,可以使用其重载方法
内容:
    提供autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck)所有能力
    提供initializeBean(Object existingBean, String beanName)所有能力
    
void autowireBean(Object existingBean) throws BeansException;
作用:主要用于(再次)填充指定Bean被注解的元素或方法(@Resource @Autowired),不执行传统的autowiring;即通过调用给定Bean的after-instantiation及post-processing接口,对bean进行装配值
    1.此方法主要是用于处理Bean中带有注解的字段和方法。
    2.此方法并不意味着by-name或者by-type方式的自动装配,如果需要使用这些功能,可以使用其重载方法autowireBeanProperties
    3.只会调用populateBean
内容:
    执行InstantiationAwareBeanPostProcessor的后置处理逻辑,因为这是在populateBean()中执行的
    不执行传统的autowiring
    不执行initializeBean方法,因此也就不执行标准的BeanPostProcessor
    
Object configureBean(Object existingBean, String beanName) throws BeansException;
作用:配置参数中指定的bean,包括自动装配其域,对其应用如setBeanName功能的回调函数。作为initializeBean的超集存在,功能跟createBean(Class<T> beanClass)类似,但要求beanName对应的BeanDefinition存在,否则会抛出NoSuchBeanDefinitionException异常,使用场景很少。
    1.并且会调用其所有注册的postprocessor.
    2.此方法提供的功能是initializeBean方法的超集,会应用所有注册在bean defineneition中的操作
    3.不过需要BeanFactory中有参数中指定名字的BeanDefinition.
    4.beanName表示在Bean定义中的名称。
    5.populateBean和initializeBean都会被调用

4.2.3、 用于对bean生命周期进行细粒度控制的专门方法

细粒度体现在以下几个方面:

  1. 提供了可选的装配模式(autowireMode)
  2. 把装配Bean的过程细化为 属性填充(populateBean) 与 初始化(initializeBean) 两个阶段
  3. 提供了BeanPostProcessors的前后置处理逻辑回调
  4. 提供了销毁Bean的逻辑回调
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
作用:创建一个指定class的实例,通过参数可以指定其自动装配模式(by-name or by-type)
    1.会执行所有注册在此class上用以初始化bean的方法.BeanPostProcessors2.Bean定义的默认值为:autowireMode = AUTOWIRE_NO;显然是不会开启自动装配的
    3.populateBean()给属性赋值(依赖注入的时候,会使用到此模式)
-----------------------------------------------------------------------------------------------------------------------------------------
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
作用:通过指定的自动装配策略来初始化一个Bean 注意:他会创建一个新的Bean
    1.需要注意的是:此方法不会调用Bean上注册的诸如BeanPostProcessors的回调方法
    2.只会调用populateBean

void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
        throws BeansException;
作用:通过指定的自动装配方式来对给定的已经存在的Bean进行自动装配
    1.不过会调用指定Bean注册的BeanPostProcessors等回调函数来初始化Bean2.如果指定装配方式为AUTOWIRE_NO的话,不会自动装配属性,但是,但是,但是依然会调用BeanPiostProcesser等回调方法。
	3.只会调用populateBean

void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
作用:简单的说,就是把Bean定义信息里面的一些东西,赋值到已经存在的Bean里面(真正执行Bean属性值的填充)
    1.除了InstantiationAwareBeanPostProcessor的回调方法外,此方法不会在Bean上应用其它的例如BeanPostProcessors
-----------------------------------------------------------------------------------------------------------------------------------------
Object initializeBean(Object existingBean, String beanName) throws BeansException;
作用: 初始化给定的Bean,会调用所有的postProcessors 方法
内容:
    1.执行invokeAwareMethods方法(xxxAware,如BeanNameAware)
    2.执行BeanPostProcessor前置处理逻辑
    3.执行invokeInitMethods进行初始化,如InitializingBeanorg#afterPropertiesSet等
    4.执行BeanPostProcessor后置处理逻辑
-----------------------------------------------------------------------------------------------------------------------------------------
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
        throws BeansException;
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException;
作用:调用参数中指定Bean的postProcessBeforeInitialization/postProcessorsAfterInitialization方法  初始化之前、之后
-----------------------------------------------------------------------------------------------------------------------------------------
void destroyBean(Object existingBean);
作用:销毁参数中指定的Bean,同时调用此Bean上的DisposableBeanDestructionAwareBeanPostProcessors方法
    1.在销毁途中,任何的异常情况都只应该被直接捕获和记录,而不应该向外抛出。

4.2.4、委托用于解析注入点的方法

<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
作用:根据传入的类型,从Spring容器(包括父子容器)中查找出指定类型下唯一的Bean,并将beanName与beanInstance包装成NamedBeanHolder对象返回。
    1.该方法其实是BeanFactory#getBean(java.lang.Class<T>)方法的变种,二者底层实现是一样的
    2.如果该类型下有不止一个对象(非唯一),返回nullObject resolveBeanByName(String name, DependencyDescriptor descriptor) throws BeansException;
作用:根据name跟descriptor解析出一个Bean实例
    1.该方法是BeanFactory#getBean(java.lang.String, java.lang.Class<T>)方法的变种
    
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
作用:解析出在Factory中与指定Bean有指定依赖关系的Bean@Autowired依赖注入的核心方法)(直接调用下边的方法)

@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
        @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
作用:解析指定bean在Factory中的依赖关系
descriptor 依赖描述 (field/method/constructor)
requestingBeanName 依赖描述所属的Bean
autowiredBeanNames 与指定Bean有依赖关系的Bean
typeConverter 用以转换数组和连表的转换器
return 结果可能为null,因为容器中可能不存在这个依赖

三级接口-ConfigurableBeanFactory

5.1、描述

特性:可配置性

可配置的 BeanFactory,声明了对 BeanFactory 各种各样的配置能力,如 bean 的作用域,bean 的 classLoader,bean 的元数据缓存,bean 的表达式解析器,类型转换器,属性编辑器等。实现此接口即拥有对 BeanFactory 的配置能力。

5.2、方法解析(38个)

5.2.1、属性

String SCOPE_SINGLETON = "singleton";
String SCOPE_PROTOTYPE = "prototype";
作用:定义了两个作用域: 单例和原型.可以通过registerScope来添加.

5.2.2、父工厂设置*

void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
作用:	父工厂设置.而且一旦设置了就不让修改(改就抛错)
	1.配合父接口HierarchicalBeanFactory的getParentBeanFactory方法

5.2.3、类加载器设置

void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
@Nullable
ClassLoader getBeanClassLoader();
作用:类加载器设置与获取.默认使用当前线程中的类加载器

5.2.4、临时类加载器设置

void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
@Nullable
ClassLoader getTempClassLoader();
作用:为了类型匹配,搞个临时类加载器.好在一般情况为null,使用上面定义的标准加载器

5.2.5、缓存元数据设置

void setCacheBeanMetadata(boolean cacheBeanMetadata);
boolean isCacheBeanMetadata();
作用:设置、是否缓存元数据,如果false,那么每次请求实例,都会从类加载器重新加载(热加载)
1.在字段mergedBeanDefinitions里存着,和getMergedBeanDefinition方法有关

5.2.6、表达式解析器设置

void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
@Nullable
BeanExpressionResolver getBeanExpressionResolver();
作用:定义用于解析bean definition的表达式解析器
1.为beanDefinition值中的表达式提供解决策略.默认的BeanFactory里是没有激活的表达式支持的.
2.一个ApplicationContext通常会设置一个标准的表达式策略,以一种统一的EL兼容风格支持“#{}”表达式.

5.2.7、类型转化器设置

void setConversionService(@Nullable ConversionService conversionService);
@Nullable
ConversionService getConversionService();
作用:类型转化器 设置和获取ConversionService接口,进行数据类型转换

5.2.8、自定义的类型转换器设置

void setTypeConverter(TypeConverter typeConverter);
TypeConverter getTypeConverter();
作用: 设置或获取自定义的类型转换器
1.BeanFactory用它来对Bean的属性值,构造参数等进行转换.这将会覆盖默认的PropertyEditor机制
2.因此,使用无关的自定义Editor或自定义Editor Registrars.因为TypeConverter通常不是线程安全的,所以每次调用都会产生一个新的实例.
3.如果默认的PropertyEditor机制被激活,获取typeConverter方法将会返回所有已被注册的自定义的typeConverter

5.2.9、String值解析器设置

void addEmbeddedValueResolver(StringValueResolver valueResolver);
作用:用来增加一个嵌入式的StringValueResolver(string值解析器),比如说注解的属性.可以参考SpringMVC中的ArgumentResolver.

boolean hasEmbeddedValueResolver();
作用:确定是否有一个嵌入式的value resolver已经在这个bean factory中注册了,并且可以通过resolveEmbeddedValue函数来应用.

@Nullable
String resolveEmbeddedValue(String value);
作用:决定一个给定的嵌入式的值,例如注解中的属性。用注册的值解析器,依次解析这个value(注意是依次解析)。谁先解析出为null了,后面就不再解析了

5.2.10、Bean创建状态控制设置

void setCurrentlyInCreation(String beanName, boolean inCreation);
boolean isCurrentlyInCreation(String beanName);
作用:bean创建状态控制.在解决循环依赖时有使用   inCreation 设置一个Bean是否正在创建

5.2.11、属性编辑器

void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
作用;添加一个PropertyEditorRegistrar应用于所有bean的创建过程.
1.一个Registrar(属性编辑器的登记员)创建了一个新的PropertyEditor实例,并且会将他们注册到一个给定的Registry,并尝试刷新每个bean的创建.
2.这就避免了自定义Editor的同步应用需求.因此通常更倾向于使用这个方法来代替registerCustomEditor.

void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
作用;为所有给定类型的属性注册一个给定的自定义属性编辑器.通常在factory配置期间被调用.
1.注意这个方法注册一个共享的自定义属性编辑器实例;为了线程安全,需要授权该实例去进行同步操作.
2.通常更倾向于使用addPropertyEditorRegistrar来代替这个方法,这就避免了自定义编辑器同步的需要

void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
作用:使用一个已经在BeanFactory里注册过的自定义属性编辑器来初始化给定的PropertyEditorRegistry.

5.2.12、BeanPostProcessor添加*

void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
作用:添加一个新的BeanPostProcessor,通过这个工厂所创建的beans将会应用这个后置处理器.
    1.在工厂的配置期间调用.注意这里的Post-processor提交将会按着registration的顺序被依次应用.
    2.任何通过Ordered这个接口所实现的顺序语义将会被忽略.也要注意到自动检测的后置处理器将会在以编程方式注册的那些后置处理		器之后执行.
    3.需要注意的是:内部实现是先执行remove,再add的设计技巧

int getBeanPostProcessorCount();
作用:获取已经注册的Bean后置处理器的个数

5.2.13、Scope作用域

void registerScope(String scopeName, Scope scope);
作用:注册一个给定的scope,支持Scope的实现类

String[] getRegisteredScopeNames();
作用:返回所有当前注册过的scope的名字.
1.这个方法只返回明确注册过的scope的名字,内置的(Built-in)scopes像”singleton”和”prototype”不会被暴露
2.如果没有返回的是空数组.

@Nullable
Scope getRegisteredScope(String scopeName);
作用:如果有的话,返回给定名字的Scope实现.和上一个函数一样,将只返回明确注册过的scope
1.内置的(Built-in)scopes像”singleton”和”prototype”不会被暴露.

5.2.14、别名设置

void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
作用:给定一个bean的名字,创建它的别名. 内部还会checkForAliasCircle(name, alias)
    1.这个方法的典型应用是支持那些在XML的ids里是无效的名字(被用于Bean的命名)
    2.通常都是在factory的配置期间被调用,但是也可以用于别名的registration的运行时.

void resolveAliases(StringValueResolver valueResolver);
作用:处理所有目标名称的别名和在这个工厂注册过的别名,然后为它们应用给定的StringValueResolver.
 这个value resolver是处理像目标bean名称甚或在别名名称里的占位符而设置的.

5.2.15、bean依赖

void registerDependentBean(String beanName, String dependentBeanName);
作用:为给定名称的Bean注册一个依赖Bean,并且该依赖Bean会在给定的Bean被销毁之前进行销毁
    1.处理bean依赖问题

String[] getDependentBeans(String beanName);
作用:如果有的话,返回依赖于给定名字Bean的所有Bean名称.

String[] getDependenciesForBean(String beanName);
作用:如果有的话,返回给定名字Bean所依赖的所有Bean名称.(注意和上面的区别,是反过来的)

5.2.16、访问权限控制

AccessControlContext getAccessControlContext();
作用:访问权限控制:返回本工厂的一个安全访问上下文  和java.security有关的

5.2.17、拷贝配置信息

void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
作用:从给定的工厂中拷贝所有相关的配置信息.
    1.应该包括了所有标准的配置,也包括了BeanPostProcessor,Scopes和factory-specific内置的一些配置.
    2.应该不包括任何真实Bean的metadata信息,BeanDefinition对象和bean的别名等

5.2.18、合并BeanDefinition*

BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
作用:返回一个给定名字的合并后的BeanDefinition,如果有必要会将子BeanDefinition和父BeanDefinition进行合并.
    1.并且也会考虑祖先容器中的BeanDefinition

5.2.19、是否是FactoryBean类型

boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
作用:是否是FactoryBean类型  判断指定Bean是否为一个工厂Bean

5.2.20、销毁bean

void destroyBean(String beanName, Object beanInstance);
作用: 依据BeanDefinition,销毁给定Bean的实例,(通常会从这个工厂中获取一个原型实例).在销毁期间所抛出的任何异常都应该用捕获来取代往这个方法的调用者那里抛出.

void destroyScopedBean(String beanName);
作用:如果有的话,在当前目标Scope中销毁指定的ScopeBean.在销毁期间所抛出的任何异常都应该用捕获来取代往这个方法的调用者那里抛出

void destroySingletons();
作用:销毁这个工厂中所有的singleton bean,包括一次性的已经注册的内嵌Bean.在工厂关闭的时候会被调用.在销毁期间所抛出的任何异常都应该用捕获来取代往这个方法的调用者那里抛出.

四级接口-ConfigurableListableBeanFactory

6.1、描述

ConfigurableListableBeanFactory 提供bean definition的解析,注册功能,再对单例来个预加载(解决循环依赖问题)。工厂接口ConfigurableListableBeanFactory同时继承了3个接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory,扩展之后,加上自有的8个方法,这个工厂接口总共有83个方法。这个工厂接口的自有方法总体上只是对父类接口功能的补充,包含了BeanFactory体系目前的所有方法,可以说是接口的集大成者。

6.2、方法解析(10个)

6.2.1、设置忽略的依赖关系

void ignoreDependencyType(Class<?> type);
作用:忽略的自动注入的类型。也就是说这些类型不能@Autowiredvoid ignoreDependencyInterface(Class<?> ifc);
作用:在装配的时候忽略指定的依赖接口.具有代表性的是application context使用这个函数来注册以其他方式解析的依赖,BeanFactory通过BeanFactoryAware或者ApplicationContext通过ApplicationContextAware.默认的情况下,只有BeanFactoryAware会被忽略.想使更多类型被忽略的话,可以为每一个想要被忽略的类型调用这个函数

6.2.2、注册找到的特殊依赖

void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);
作用:注册一个可以给解析的依赖。这样子注入进去的,在Autowired的时候就可以被自动注入进去了,即使不在容器里面
解释:注册一个指定的依赖类型并放入可供注入的值.这个函数是给factory/context 引用用的,是为了自动注入那些没有作为Bean被注册在Factory中的那些实体类.例如, Bean内部的ApplicationContext类型的依赖会被解析为一个ApplicationContext实例.注意:在一个扁平的BeanFactory中没用默认的类型被注册,甚至连BeanFactory接口自己都没有.

6.2.3、判断指定的Bean是否有资格作为自动装配的候选者

boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException;
作用:判断指定的Bean是否有资格作为自动装配的候选者。
解释:确定一个指定的Bean是否有资格作为自动注入的候选,如果有的话,它将可能会被注入到那些声明了匹配类型依赖的其它Bean,这个方法也会检查父级的factory.

6.2.4、获取bean定义 (可以访问属性值跟构造方法的参数值)

BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
作用: 返回注册的Bean定义(这个比较常用)  它可以拿到单独的某个Bean定义信息(ListableBeanFactory都是批量的返回)。
解释:返回为指定Bean注册的BeanDefinition,并允许访问他的属性值和构造函数参数值.(这些属性值都可以在beanfactory中的post-processing进行修改) 返回的BeanDefinition对象不是一个拷贝而是在factory中注册过的原生definition对象.这也就意味着如果有必要的话,该对象应该会被转换成一个更具体的实现类型.注意: 这个方法不会考虑祖先级容器.这个方法只是为本地factory中的bean definition来服务的.

Iterator<String> getBeanNamesIterator();
作用:为所有被这个工厂所管理的Bean的名称返回一个统一的视图.包括bean definition的名字也包括手动注册的单例实例的名字,一贯地是BeanDefinition名字优先.类似于指定类型/注解的bean名字的检索工作.

6.2.5、清理元数据的缓存

void clearMetadataCache();
作用:清理被合并的BeanDefinition缓存,也会移除那些元数据缓存不完整的那些Bean的实体.典型的应用场景是在原生的bean definitions被改变之后触发该函数.例如,在应用了一个BeanFactoryPostProcessor之后.注意:在这一时刻已经被创建的Bean的元数据不受影响.

6.2.6、锁定配置信息.在调用refresh时会使用到

void freezeConfiguration();
作用:暂时冻结所有的Bean配置。冻结所有的BeanDefinition,以及已被注册过的BeanDefinition将不会被修改或任何进一步post-processed的信息.这个函数允许factory侵入性地缓存beanDefinition元数据信息.

boolean isConfigurationFrozen();
作用:返回工厂中的beanDefinition是否是被冻结的

6.2.7、预加载不是懒加载的单例.用于解决循环依赖问题

void preInstantiateSingletons() throws BeansException;
作用:使所有的非延迟加载的单例类都实例化。确保所有non-lazy-init的单例被实例化,也包括FactoryBeans.如果有需求的话,通常是在factory启动的最后调用这个方法.

抽象类-AbstractBeanFactory

7.1、描述

AbstractBeanFactory作为一个抽象类,实现了三级接口ConfigurableBeanFactory(方法50+的接口)大部分功能。
而且继承自FactoryBeanRegistrySupport,所以它也具备了SingletonBeanRegistry和SimpleAliasRegistry的能力。
... 实现了大部分的方法,其中最终的实现为getBean()/doGetBean()方法的实现,提供了模版。其实createBean抽象方法,还是子类去实现的
... isSingleton(String name) / isPrototype(String name) / containsBean(String name) 也能实现精准的判断了

这里面的方法主要分一下几类,第一种就是 BeanFactory接口的实现,第二种就是HierarchicalBeanFactory接口的实现 ,第三种就是 ConfigurableBeanFactory接口的实现,第四种是自己的内部方法,第五种就是抽象方法,需要由子类实现

7.2、方法分析

7.2.1、属性

//父类容器
@Nullable
private BeanFactory parentBeanFactory;
//类加载器
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
//临时加载器
@Nullable
private ClassLoader tempClassLoader;
//是否开启 bean元数据缓存 1.是用 bean元数据缓存还是每次访问时重新获取
private boolean cacheBeanMetadata = true;
//bean的表达式解析器
@Nullable
private BeanExpressionResolver beanExpressionResolver;
//类型转换器
@Nullable
private ConversionService conversionService;
//属性编辑器
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
//类的属性编辑器
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4);
//类型转换器
@Nullable
private TypeConverter typeConverter;
//为嵌入的值(如注释属性)添加字符串解析器
private final List<StringValueResolver> embeddedValueResolvers = new CopyOnWriteArrayList<>();
//后置处理器
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
//InstantiationAwareBeanPostProcessors是否已注册
private volatile boolean hasInstantiationAwareBeanPostProcessors;
//DestructionAwareBeanPostProcessors是否已注册
private volatile boolean hasDestructionAwareBeanPostProcessors;
//作用域
private final Map<String, Scope> scopes = new LinkedHashMap<>(8);
//提供安全作用域
@Nullable
private SecurityContextProvider securityContextProvider;
//合并后的BeanDefinition
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
/** Names of beans that have already been created at least once. */
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
// 本地缓存,正在创建的多例bean。这边用本地线程,是因为其他线程创建bean与当前线程不冲突
private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal<>("Prototype beans currently in creation"); 

7.2.2、BeanFactory接口的实现

实现方法,不多赘述,省略

7.2.3、HierarchicalBeanFactory接口方法的实现

实现方法,不多赘述,省略

7.2.4、ConfigurableBeanFactory接口的实现

实现方法,不多赘述,省略

7.2.5、由子类实现的抽象方法

// 效果同:ListableBeanFactory#containsBeanDefinition  实现类:DefaultListableBeanFactory
protected abstract boolean containsBeanDefinition(String beanName);
// 效果同:ConfigurableListableBeanFactory#getBeanDefinition  实现类:DefaultListableBeanFactory
protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
// 创建Bean的复杂逻辑,子类去实现。(子类:AbstractAutowireCapableBeanFactory)
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)  throws BeanCreationException;

抽象类-AbstractAutowireCapableBeanFactory

8.1、描述

提供bean创建(构造函数创建),属性装配(population),织入 autowiring 
1.最重要的是实现了doCreateBean()的创建逻辑,然后执行队形的BeanPostProcessor
2.applyPropertyValues():这里做的大部分工作就是依赖的准备工作
3.然后对bean实例化、初始化、并完成了它的依赖注入入口(具体逻辑由子类DefaultListableBeanFactory具体去实现)
4.它实现了对Bean的实例化、populateBean()、以及initializeBean(),会对Bean进行注入等操作
5.当然也管理了一些ignoredDependencyTypes,忽略的依赖等等

8.2、方法分析

8.2.1、属性

// bean生成策略,默认CGlib
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
// 解析方法参数的名字
@Nullable
private ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
/** Whether to automatically try to resolve circular references between beans. */
private boolean allowCircularReferences = true;
//在循环引用的情况下,是否需要注入一个原始的bean实例
private boolean allowRawInjectionDespiteWrapping = false;
// 这两个保存的类型,是ignore on dependency check and autowire(字段装配时,如果在这里面的类型讲被忽略)
// 使用:我们可以自己忽略类型:beanFactory.ignoreDependencyType(ArrayList.class); 比如在BeanFactoryPostProcessor 这里可以这么做
// 他们有些区别:因为平时使用较少,却别这里就不详细介绍了
// 总之,若你自己想忽略特定类型的自动注入的话,推荐使用ignoredDependencyTypes
private final Set<Class<?>> ignoredDependencyTypes = new HashSet<>();
// 在依赖检查,自动装配  忽略的接口集合 如 BeanNameAware,BeanFactoryAware,BeanClassLoaderAware
private final Set<Class<?>> ignoredDependencyInterfaces = new HashSet<>();
private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");
// factoryBean name 和 BeanWrapper的映射
private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>();
/** Cache of candidate factory methods per factory class. */
private final ConcurrentMap<Class<?>, Method[]> factoryMethodCandidateCache = new ConcurrentHashMap<>();
// 类和 PropertyDescriptor的映射
private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache = new ConcurrentHashMap<>();

8.2.2、构造器

// 父类空构造器有这么些语句
public AbstractAutowireCapableBeanFactory() {
    super();
    // 这里是重点。忽略自动装配。这里指定的都是接口。什么意思呢?
    // ignoreDependencyInterface的真正意思是在自动装配时忽略指定接口的实现类中,对外的依赖。
    // 这里面注意:@Autowired和它的关系,其实是有坑的
    ignoreDependencyInterface(BeanNameAware.class);
    ignoreDependencyInterface(BeanFactoryAware.class);
    ignoreDependencyInterface(BeanClassLoaderAware.class);
}

// 给设置父的BeanFactory,若存在的话
public AbstractAutowireCapableBeanFactory(@Nullable BeanFactory parentBeanFactory) {
    this();
    setParentBeanFactory(parentBeanFactory);
}

8.2.3、创建和装配外部bean实例

实现方法,不多赘述,省略

8.2.4、用于对bean生命周期进行细粒度控制的专门方法

实现方法,不多赘述,省略

8.2.5、相关AbstractBeanFactory模板方法的实现

实现方法,不多赘述,省略

最终类-DefaultListableBeanFactory

9.1、描述

BeanDefinitionRegistry bean定义信息注册中心
Spring内部的唯一使用的工厂实现(XmlBeanFactory已废弃)基于bean definition对象,是一个成熟的bean factroy
默认实现了ListableBeanFactoryBeanDefinitionRegistry接口,基于bean definition对象,是一个成熟的bean factroy。
它是整个bean加载的核心部分,也是spring注册加载bean的默认实现
// extends:相当于继承了抽象类所有的实现,并且是已经具有注入功能了(含有ListableBeanFactory、ConfigurableListableBeanFactory的所有接口)
// implements:直接实现ConfigurableListableBeanFactory,表示它具有了批量处理Bean、配置Bean等等功能
// BeanDefinitionRegistry:该接口目前还仅有这个类实现(它父接口为:AliasRegistry	)

9.2、方法分析

9.2.1、属性

@Nullable
private static Class<?> javaxInjectProviderClass;

static {
    try {
        javaxInjectProviderClass =
                ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
    }
    catch (ClassNotFoundException ex) {
        // JSR-330 API not available - Provider interface simply not supported then.
        javaxInjectProviderClass = null;
    }
}

/** Map from serialized id to factory instance. */
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
        new ConcurrentHashMap<>(8);
/** Optional id for this factory, for serialization purposes. */
@Nullable
private String serializationId;
/** Whether to allow re-registration of a different definition with the same name. */
private boolean allowBeanDefinitionOverriding = true;
/** Whether to allow eager class loading even for lazy-init beans. */
private boolean allowEagerClassLoading = true;
/** Optional OrderComparator for dependency Lists and arrays. */
@Nullable
private Comparator<Object> dependencyComparator;
/** Resolver to use for checking if a bean definition is an autowire candidate. */
private AutowireCandidateResolver autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;
/** Map from dependency type to corresponding autowired value. */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
/** Map of bean definition objects, keyed by bean name. */
//beanDefinition容器
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** Map from bean name to merged BeanDefinitionHolder. */
private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256);
/** Map of singleton and non-singleton bean names, keyed by dependency type. */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
/** Map of singleton-only bean names, keyed by dependency type. */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
/** List of bean definition names, in registration order. */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
/** List of names of manually registered singletons, in registration order. */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<>(16);
/** Cached array of bean definition names in case of frozen configuration. */
@Nullable
private volatile String[] frozenBeanDefinitionNames;
/** Whether bean definition metadata may be cached for all beans. */
private volatile boolean configurationFrozen;

9.2.2、BeanFactory接口的实现

实现方法,不多赘述,省略

9.2.3、ListableBeanFactory接口的实现

实现方法,不多赘述,省略

9.2.4、ConfigurableListableBeanFactory接口的实现

实现方法,不多赘述,省略

9.2.5、BeanDefinitionRegistry接口的实现

实现方法,不多赘述,省略

9.2.6、依赖性解析功能

实现方法,不多赘述,省略

9.2.7、序列化支持

实现方法,不多赘述,省略

引用

https://www.cnblogs.com/coder-zyc/p/15820514.html
https://blog.csdn.net/gududedabai/article/details/83178043
https://docs.spring.io/spring-framework/docs/5.2.x/javadoc-api/overview-summary.html
https://blog.csdn.net/iycynna_123/article/details/52879969
https://blog.csdn.net/likunpeng6656201/article/details/100598312

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

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

相关文章

SAP ABAP——SAP包(二)【CTS | 传输请求】

&#x1f482;作者简介&#xff1a; THUNDER王&#xff0c;一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计专业大二本科在读&#xff0c;阿里云社区专家博主&#xff0c;华为云社区云享专家&#xff0c;CSDN SAP应用技术领域新兴创作者。   在学习工…

CentOS7.9配置Nginx反向代理+NodeJS部署上线

Nginx配置 Nginx是一个高性能的HTTP和反向代理服务&#xff0c;许多的大型网站都会采用Nginx来进行HTTP服务器托管 安装编译环境gcc g 进入到root目录&#xff1a; yum -y install make zlib zlib-devel gcc-c libtool openssl openssl-devel 安装PCRE PCRE功能时让Ngi…

ue4c++日记3(碰撞报告碰撞位置|力和扭矩)

目录 代码速查 根据世界方向/局部方向移动 根据世界方向/局部方向旋转 加力加扭矩 1碰撞并报告碰撞位置 两个设为阻挡才会阻挡&#xff0c;其中一个是重叠就会重叠 2例子&#xff1a;旋转前进&#xff01;/原地踏步&#xff1f; 3增加力和扭矩 1.头文件 2.cpp文件 …

(14)go-micro微服务服务层Handle开发

文章目录一 Handle层开发功能说明需要完成的服务开发功能&#xff1a;从哪找需要开发的功能二 代码编写三 最后一 Handle层开发功能说明 需要完成的服务开发功能&#xff1a; 登录注册查询用户信息修改信息发送注册邮件发送重置密码邮件重置密码获取权限修改权限退出账号删除…

【计算机视觉】梯度消失和爆炸以及解决方法

问题 梯度消失无论是笔试还是面试都是常客了,其实对应于梯度消失,还有一个梯度爆炸的概念,这又是什么导致的呢?下面我们将根据公式推导来解释何为梯度消失与梯度爆炸。 梯度消失和梯度爆炸的表现 网络层数越多,模型训练的时候便越容易出现 梯度消失(gradient vanish) 和…

史上最全| 14种自动化分拣系统合集

导语大家好&#xff0c;我是智能仓储物流技术研习社的社长&#xff0c;你的老朋友&#xff0c;老K。新书上市《智能物流系统构成与技术实践》2023年度-厂商宣传合作位--->点击详情本文为研习社原创&#xff0c;违规转载必究01移栽式02偏转轮式03扫臂式04滑靴式05侧向翻转06推…

C++设计模式(3)——抽象工厂模式

抽象工厂模式 亦称&#xff1a; Abstract Factory 意图 抽象工厂模式是一种创建型设计模式&#xff0c; 它能创建一系列相关的对象&#xff0c; 而无需指定其具体类。 问题 假设你正在开发一款家具商店模拟器。 你的代码中包括一些类&#xff0c; 用于表示&#xff1a; …

Vue3系列二:如何实现对响应式数据的代理

上一篇文章中&#xff0c;我们讲解了 Vue3 中对响应式系统的实现&#xff0c;本章节会更进一步的从数据层面分享 Vue3 中对响应式数据是如何进行代理的&#xff0c;本文主要从引用类型数据和基本类型数据两个方面进行讲解。 实现数据代理的基础 理解 Proxy 和 Reflect 首先&…

26.Isaac教程--导航算法

导航算法 本节详细介绍导航算法。 ISAAC教程合集地址: https://blog.csdn.net/kunhe0512/category_12163211.html 文章目录导航算法全局路径规划器规划器模型可见性图算法优化器轨迹规划器全局路径规划器 Isaac 框架中的全局规划器问题被分解为三类&#xff1a;规划器模型、…

SpringBoot使用Swagger2

SpringBoot使用Swagger21.引入swagger依赖2.添加swagger配置类3.测试Controller4.测试5.swagger的注解Api注解ApiOperation注解ApiImplicitParam、ApiImplicitParams注解ApiParam注解ApiResponse、ApiResponses注解ResponseHeader注解ApiModel、ApiModelProperty注解6.更多1.引…

Redis 分布式锁实现文章集锦

前言近两年来微服务变得越来越热门&#xff0c;越来越多的应用部署在分布式环境中&#xff0c;在分布式环境中&#xff0c;数据一致性是一直以来需要关注并且去解决的问题&#xff0c;分布式锁也就成为了一种广泛使用的技术&#xff0c;常用的分布式实现方式为Redis&#xff0c…

PDF压缩在线怎么操作?这几个操作谁还不知道

我们在工作里经常处理非常多的文件&#xff0c;如果每个文件都要储存到设备上是非常困难的&#xff0c;因为这需要占用大量的内存&#xff0c;所以我们需要将PDF文件进行压缩&#xff0c;这样就可以释放我们设备的储存空间&#xff0c;不过对于很多人来说&#xff0c;压缩文件并…

自学Java篇之JFrame创建《石头迷阵小游戏》

自学Java篇之JFrame创建《石头迷阵小游戏》 根据黑马程序员java教程自学完java基础&#xff0c;觉得石头迷阵小游戏案例具有一定的编程练习价值&#xff0c;记录之。 最终效果&#xff1a; 案例主要思想流程&#xff1a; ​ 主要是思想是创建一个4*4的二维数组data&#xff…

【openGauss实战5】表管理及CURD

&#x1f4e2;&#x1f4e2;&#x1f4e2;&#x1f4e3;&#x1f4e3;&#x1f4e3; 哈喽&#xff01;大家好&#xff0c;我是【IT邦德】&#xff0c;江湖人称jeames007&#xff0c;10余年DBA工作经验 一位上进心十足的【大数据领域博主】&#xff01;&#x1f61c;&#x1f61…

汽车网络技术概述

车辆总线是一个专门的内部通信网络&#xff0c;将车辆&#xff08;如汽车、公共汽车、火车、工业或农业车辆、船舶或飞机&#xff09;内的部件相互连接。在电子学中&#xff0c;总线只是一个将多个电气或电子设备连接在一起的设备。车辆控制的特殊要求&#xff0c;如保证信息传…

数据分析-深度学习 Pytorch Day7

图像识别&#xff1a;CIFAR10图形识别1.CIFAR10数据集共有60000张彩色图像&#xff0c;这些图像式32*32*3&#xff0c;分为10个类&#xff0c;每个类6000张2.这里面有50000张用于训练&#xff0c;构成5个训练批&#xff0c;每一批10000张图&#xff1b;另外10000张用于测试&…

vhdx中的win10进行大版本系统升级

文章目录前言普通的win10大版本iso升级方式vhdx中的win10大版本升级方式难点分析 - 无法在虚拟驱动器上安装windows解决方案 - HyperV升级vhdx win10过程效果图hyperV虚机创建mbr引导启动项hyperV虚机设置在hyperV中升级过程图问题集锦问题一&#xff1a;hyverV虚机中升级报错&…

力扣刷题记录——561. 数组拆分、566. 重塑矩阵、575. 分糖果

本专栏主要记录力扣的刷题记录&#xff0c;备战蓝桥杯&#xff0c;供复盘和优化算法使用&#xff0c;也希望给大家带来帮助&#xff0c;博主是算法小白&#xff0c;希望各位大佬不要见笑&#xff0c;今天要分享的是——《力扣刷题记录——561. 数组拆分、566. 重塑矩阵、575. 分…

IDEA远程调试

1 概述 原理&#xff1a;本机和远程主机的两个 VM 之间使用 Debug 协议通过 Socket 通信&#xff0c;传递调试指令和调试信息。 被调试程序的远程虚拟机&#xff1a;作为 Debug 服务端&#xff0c;监听 Debug 调试指令。jdwp是Java Debug Wire Protocol的缩写。 调试程序的本…

初识redis

1.初识Redis Redis是一种键值型的NoSql数据库&#xff0c;这里有两个关键字&#xff1a; 键值型 NoSql 其中键值型&#xff0c;是指Redis中存储的数据都是以key、value对的形式存储&#xff0c;而value的形式多种多样&#xff0c;可以是字符串、数值、甚至json&#xff1a;…