- 简介
- Bean 定义类型
- BeanMetadataElement
- BeanMetadataAttribute
- AttributeAccessor
- AttributeAccessorSupport
- BeanMetadataAttributeAccessor
- AutowireCandidateQualifier
- Bean 定义
- Bean 定义顶级接口:BeanDefinition
- Bean 定义抽象实现:AbstractBeanDefinition
- 通用的 Bean 定义:GenericBeanDefinition
- 注解 Bean 定义
- AnnotatedBeanDefinition
- AnnotatedGenericBeanDefinition
- ScannedGenericBeanDefinition
- 根 Bean 定义
- RootBeanDefinition
- ConfigurationClassBeanDefinition
- 另一种方式构建 Bean 定义:BeanDefinitionBuilder
学成路更宽,吊打面试官。 ——小马哥
简介
大家好,我是小马哥成千上万粉丝中的一员!2019年8月有幸在叩丁狼教育举办的猿圈活动中知道有这么一位大咖,从此结下了不解之缘!此系列在多次学习极客时间《小马哥讲Spring核心编程思想》基础上形成的个人一些总结。希望能帮助各位小伙伴, 祝小伙伴早日学有所成。 分为基础篇、进阶篇、源码篇。玩游戏看颜色,学技术看版本,本系列以 Spring 5.2.2.RELEASE 版本为基础进行介绍。 祝小伙伴早日学有所成。
Bean 定义类型
- 非根类型 BeanDefinition
- 普通类型 BeanDefinition
- 注解类型 BeanDefinition
- 根类型 BeanDefinition
BeanMetadataElement
接口由携带配置源对象的 bean 元数据元素实现
方法 | 描述 |
getSource() | 返回当前元信息元素的配置源对象 |
BeanMetadataAttribute
作为 bean 定义一部分的键-值样式属性的 Holder。跟踪除了键-值对之外的定义源。
字段 | 描述 |
final Stirng name | 属性名称,永远不为 null |
final Object value | 属性值 |
Object source | 元信息元素配置源对象 |
方法 | 描述 |
setSource(Object) | 为这个元数据元素设置配置源对象。对象的确切类型取决于所使用的配置机制 |
getName/Value() | 获取属性名/值 |
AttributeAccessor
接口定义用于向任意对象附加元数据和从任意对象访问元数据的通用契约(大量使用在框架内部)
方法 | 描述 |
setAttribute(String, Object) | 将 name 定义的属性设置为提供的值。如果 value 为空,则删除该属性。一般来说,用户应该注意使用完全限定名(可能使用类名或包名作为前缀)来防止与其他元数据属性的重叠 |
getAttribute(String) | 获取按名称标识的属性的值。如果属性不存在,则返回 null |
removeAttribute(String) | 删除由 name 标识的属性并返回其值。如果 name下没有找到属性,则返回 null |
hasAttribute(String) | 如果以 name 标识的属性存在,则返回 true。否则返回 false |
attributeNames() | 返回所有属性的名称 |
AttributeAccessorSupport
支持 AttributeAccessors 类,基于 LikeHashMap 来提供所有方法的基本实现。由子类扩展的。如果子类和所有属性值都是可序列化的。
字段 | 描述 |
Map<String, Object> attributes = new LikedHashMap<>() | 用来保存属性的 key 和 value |
方法 | 描述 |
copyAttributeFrom(AttributeAccessor) | 将属性从提供的 AttributeAccessor 复制到此 AttributeAccessor |
BeanMetadataAttributeAccessor
持有一部分作为 bean 定义的键-值样式属性。跟踪除了键-值对之外的定义源。
字段 | 描述 |
Object source | 配置源对象 |
方法 | 描述 |
setSource(Object) | 为这个元数据元素设置配置源Object。对象的确切类型取决于所使用的配置机制 |
addMetadataAttribute(BeanMetadataAttribute) | 将给定的 BeanMetadataAttribute 添加到该访问器的属性集 |
getMetadataAttribute(String) | 在这个访问器的属性集中查找给定的BeanMetadataAttribute |
AutowireCandidateQualifier
解决自动装配候选人的限定符。包含一个或多个这样的限定符的 bean 定义允许对自动装配的字段或参数上的注解进行细粒度匹配。主要用于解析 @Qualifier 注解。
字段 | 描述 |
String VALUE_KEY = “Value” | 用于存储值的键的名称 |
String typeName | 被 @Qualifier 注解标注类型的名称 |
方法 | 描述 |
getTypeName() | 检索类型名称。如果将 Class 实例提供给构造函数,则此值将与提供给构造函数的类型名相同,或者与提供给构造函数的完全限定类名相同 |
Bean 定义
Bean 定义顶级接口:BeanDefinition
BeanDefinition 描述一个 bean 实例,该实例具有属性值、构造函数参数值和具体实现提供的进一步信息。这只是一个最小的接口:主要目的是允许 BeanFactoryPostProcessor 内省和修改属性值和其他 bean 元数据。
常量字段 | 描述 |
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON | 标准单例作用域的作用域标识:singleton |
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE | 标准原型作用域的作用域标识符:prototype |
int ROLE_APPLICATION = 0 | 角色提示,表明 BeanDefinition 是应用程序的主要部分。通常对应于用户定义的 bean |
int ROLE_SUPPORT = 1 | 角色提示,表明 BeanDefinition 是某些较大配置的支持部分,通常是外部 ComponentDefinition。当更仔细地查看特定的 ComponentDefinition 时,支持 bean 被认为是非常重要的,但当查看应用程序的总体配置时,就不需要注意了 |
int ROLE_INFRASTRUCTURE= 2 | 角色提示,表明 BeanDefinition 提供的是一个完全的后台角色,与最终用户无关。当注册完全是 ComponentDefinition 内部工作的一部分的bean时,将使用此提示 |
方法 | 描述 |
setParentName(String) | 设置此 bean 定义的父定义的名称(如果有的话) |
getParentName() | 返回此 bean 定义的父定义的名称(如果有的话) |
setBeanClassName(String) | 指定此 bean 定义的 bean 类名。可以在 bean 工厂后处理期间修改类名,通常用已解析的类名变体替换原来的类名 |
getBeanClassName() | 返回此 bean 定义的当前 bean 类名。请注意,这并不一定是运行时使用的实际类名,以防子定义重写/继承其父类名。此外,这可能只是调用工厂方法的类,或者在调用方法的工厂 bean 引用时,它甚至可能是空的。因此,不要将其视为运行时的最终 bean 类型,而应仅将其用于单个 bean 定义级别的解析目的 |
set/getScope() | 设置/获取 bean 当前的作用域名称 |
setLazyInit(boolean) | 设置这个 bean 是否应该延迟初始化。如果为 false,该 bean 将在启动时由执行单例的立即初始化的 bean 工厂进行实例化 |
isLazyInit() | 返回此 bean 是否应该延迟初始化,即在启动时不急切地实例化。仅适用于单例 bean |
setDependsOn(String…) | 设置初始化此 bean 所依赖的 bean 的名称。bean 工厂将确保首先初始化这些 bean |
getDependsOn() | 返回此 bean 所依赖的 bean 名称 |
setAutowireCandidate(boolean) | 设置此 bean 是否是自动装配到其他 bean 的候选 bean |
isAutowireCandidate() | 返回此 bean 是否是自动装配到其他 bean 的候选对象 |
setPrimary(boolean) | 设置此 bean 是否为主要的自动装配候选对象。如果在多个匹配的候选 bean 中只需要装配一个,则将装配值为 true 的候选对象 |
isPrimary() | 返回此 bean 是否是主要的自动装配候选对象 |
setFactoryBeanName(String) | 指定要使用的工厂 bean(如果有的话)。这是要调用指定工厂方法的 bean 的名称 |
getFactoryBeanName() | 返回工厂bean名称(如果有的话) |
setFactoryMethodName(String) | 如果有的话,请指定一个工厂方法。此方法将使用构造函数参数调用,如果没有指定参数,则不使用参数调用。该方法将在指定的工厂 bean(如果有的话)上调用,或者作为本地的静态方法调用 |
getFactoryMethodName() | 如果有工厂方法,则返回工厂方法 |
getConstructorArgumentValues() | 返回此bean的构造函数参数值。返回的实例可以在 bean 工厂后处理期间修改 |
hasConstructorArgumentValues() | 如果有为这个 bean 定义的构造函数参数值,则返回 |
getPropertyValues() | 返回要应用到 bean 的新实例的属性值。返回的实例可以在 bean 工厂后处理期间修改 |
hasPropertyValues() | 如果有为这个 bean 定义的属性值,则返回 true,否则为 false |
set/getInitMethodName() | 设置/获取 初始化方法的名称 |
set/getDestroyMethodName() | 设置/获取 销毁方法的名称 |
set/getRole() | 设置/获取 这个BeanDefinition角色提示 |
set/getDescription() | 设置/返回 这个 bean 定义的人类可读的描述 |
getResolvableType() | 根据 bean 类或其他特定元数据,返回此 bean 定义的可解析类型。这通常在运行时合并bean定义上完全解决,但不一定在配置时定义实例上 |
isSingleton() | 返回是否为 Singleton,所有调用都返回一个共享实例。 |
isPrototype() | 返回是否为 Prototype,并为每个调用返回一个独立的实例。 |
isAbstract() | 返回这个bean是否是抽象的,也就是说,不打算被实例化 |
getResourceDescription() | 返回此 bean 定义所来自的资源的描述(以便在出现错误时显示上下文)。 |
getOriginatingBeanDefinition() | 返回最初的 BeanDefinition,如果没有则返回 null。允许检索修饰过的 bean 定义(如果有的话)。注意,这个方法返回直接的发起者。遍历发起者链以找到用户定义的原始 BeanDefinition |
Bean 定义抽象实现:AbstractBeanDefinition
具体的、完整的 BeanDefinition 类的基类,提取 GenericBeanDefinition、RootBeanDefinition 和ChildBeanDefinition 的公共属性。自动装配常量与 AutowireCapableBeanFactory 接口中定义的常量相匹配。
字段 | 描述 |
final String SCOPE_DEFAULT = " " | 默认作用域名的常量:"",等同于单例状态,除非从父 bean 定义中重写(如果适用) |
final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO | 常数表示没有外部自动装配 |
final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME | 常数表示按名称自动装配 bean 属性 |
final int AUTOWIRE_BY_TYBE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE | 常量表示按按类型自动装配 bean 属性 |
final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR | 常量表示通过构自动装配造器所需 bean |
final int DEPENDENCY_CHECK_NONE = 0 | 常量表示不进行依赖检查 |
final int DEPENDENCY_CHECK_OBJECT = 1 | 常量表示对对象引用进行依赖项检查 |
final int DEPENDENCY_CHECK_SIMPLE = 2 | 常量表示对简单属性进行依赖关系检查 |
final int DEPENDENCY_CHECK_ALL = 3 | 常数表示对所有属性(对象引用以及“简单”属性)进行依赖关系检查 |
final String INFER_METHOD = “(Iinferred)” | 常数表示容器应该尝试推断 bean 的 destroy 方法名,而不是显式指定方法名。值 (Iinferred) 专门用于在方法名中包含非法字符,以确保与具有相同名称的合法命名方法不发生冲突。目前,在销毁方法推断期间检测到的方法名是 close 和 shutdown ,如果在特定的 bean 类上存在的话 |
Object beanClass | bean Class,有可能是 Class 的全限定名而不是 Class 对象 |
String scope | 作用域名称,默认是 “ ”(也是单例) |
boolean abstractFlag | 是否是抽象标识 |
boolean lazyInit | 是否是延迟初始化标识 |
int autowireMode | 自动装配模型,默认是没有外部自动装配 |
int dependencyCheck | 依赖检查,默认不进行依赖检查 |
String[] dependsOn | 依赖的 bean 先初始化 |
boolean autowireCandidate | 是否支持被别的 bean 自动装配,默认 false |
boolean primary | 是否是主要的自动装配候选对象,默认 false |
Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>() | bean 的限定符 |
Supplier<?> instanceSupplier | bean 实例的 Supplier |
boolean notPublicAccessAllowed | 非公共访问允许标志,默认 true |
boolean lenientConstructorResolution | 在宽松模式或严格模式下解析构造器,默认 true |
String factoryBeanName | 工厂 bean 名称 |
String factoryMethodName | 工厂方法名称 |
ConstructorArgumentValues constructorArgumentValues | 构造器参数值 |
MutablePropertyValues propertyValues | bean 属性值 |
MethodOverrides methodOverrides | 方法覆盖 |
String initMethodName | 初始化方法名称 |
String destroyMethodName | 销毁方法名称 |
boolean enforceInitMethod | 是否执行初始化方法标志,默认 true |
boolean enforceDestroyMethod | 是否执行销毁方法标志,默认 true |
boolean synthetic | 是否是合成 bean 标志,默认 false |
int role | bean 角色,默认是用户创建的 bean |
String description | bean 描述信息 |
Resource resource | bean 定义来自的资源 |
方法 | 描述 |
overrideFrom(BeanDefinition) | 从给定的 bean 定义(假定是子 bean)重写此 bean 定义(假定是从父子继承关系中复制的父 bean)中的设置。如果在给定的 bean 定义中指定,将重写 beanClass。总是从给定的 bean 定义中获取 abstract、scope、lazyInit、autowireMode、dependencyCheck 和 dependsOn。将添加 constructorArgumentValues, propertyValues, methodorides 从给定的bean定义到现有的。如果在给定的 bean 定义中指定,将覆盖 factoryBeanName、factoryMethodName、initMethodName和destroyMethodName |
applyDefaults(BeanDefinitionDefaults) | 将提供的默认值(延迟初始化、自动装配模型、依赖检查、初始化方法、销毁方法)应用于此 bean |
set/get/hasBeanClass() | 设置/获取/是否有 bean 类型 |
resolveBeanClass(ClassLoader) | 确定包装 bean 的类,如果需要,从指定的类名解析它。当使用已解析的 bean 类调用指定的 Class 时,也将从其名称重新加载指定的 Class |
getLazyInit() | 返回此 bean 是否应该延迟初始化,即在启动时不急切地实例化。仅适用于单例 bean |
get/setAutowireMode() | 获取/设置 自动装配模型编码 |
getResolvedAutowireMode() | 返回解析后的自动装配模型编码(解析 AUTOWIRE_AUTODETECT 为 AUTOWIRE_CONSTRUCTOR 或AUTOWIRE_BY_TYPE) |
set/getDependencyCheck() | 设置/获取 依赖项检查编码 |
add/has/getQualifier() | 添加/是否/获取 bean 的指定限定符 |
getQaulifiers() | 返回所有注册的限定符 |
copyQualifiersFrom(AbstractBeanDefinition) | 将限定符从提供的 AbstractBeanDefinition 复制到此 bean 定义 |
cloneBeanDefinition() | 克隆这个 bean 定义。由具体的子类来实现 |
prepareMethodOverride(MethodOverride) | 验证并准备给定的方法覆盖。检查具有指定名称的方法是否存在,如果未找到,则将其标记为未重载 |
prepareMethodOverrides() | 调用 prepareMethodOverride(MethodOverride) 方法 |
validate() | 主要验证 bean 定义中如果有 methodOverrides 但是又有 factoryMethodName 就会报错。如果 beanClass 已经解析过了,着准备 methodOverrides |
setOriginatingBeanDefinition(BeanDefinition) | 如果有的话,设置初始 bean 定义(例如,修饰过的 bean 定义) |
setResourceDescription(String) | 设置此 bean 定义来自的资源的描述(以便在出现错误时显示上下文) |
set/getResource() | 设置/获取 此 bean 定义来自的资源(以便在出现错误时显示上下文) |
is/setSynthetic() | 是否/设置 bean 定义是合成 |
is/setEnforceDestroyMethod() | 是否/设置 执行销毁方法 |
is/setEnforceInitMethod() | 是否/设置 执行初始化方法 |
has/set/getMethodOverrides() | 是否有/设置/获取 定义方法覆盖 |
通用的 Bean 定义:GenericBeanDefinition
- GenericBeanDefinition 是用于标准 bean 定义的一站式服务。与任何 bean 定义一样,它允许指定一个类以及可选的构造函数参数值和属性值。此外,可以通过 parentName 属性灵活地配置从父 bean 定义派生的 bean
- 通常,使用这个 GenericBeanDefinition 类注册用户可见的 bean 定义(后置处理程序可能对其进行操作,甚至可能重新配置父名称)。使用 RootBeanDefinition / ChildBeanDefinition,其中父/子关系碰巧是预先确定的。
字段 | 描述 |
String parentName | 父定义的名称 |
方法 | 描述 |
get/setParentName() | 返回/设置 此 bean 定义的父定义的名称 |
注解 Bean 定义
AnnotatedBeanDefinition
扩展的 BeanDefinition 接口暴露了关于它的 bean 类的 AnnotationMetadata —— 而不需要加载该类
方法 | 描述 |
AnnotationMetadata getMetadata() | 获取这个 bean 定义的 bean 类的注解元数据(以及基本类元数据) |
MethodMetadata getFactoryMethodMetadata() | 获取此 bean 定义的工厂方法的元数据(如果有的话) |
AnnotatedGenericBeanDefinition
- GenericBeanDefinition 类的扩展,添加了对通过 AnnotatedBeanDefinition 接口暴露的注解元数据的支持
- 这个 GenericBeanDefinition 变体主要用于测试期望在 AnnotatedBeanDefinition 上操作的代码,例如 Spring 的组件扫描支持中的策略实现(其中默认定义类是 ScannedGenericBeanDefinition,它也实现了 AnnotatedBeanDefinition 接口)
字段 | 描述 |
final AnnotationMetadata metadata | 涉及的 bean 类的注解元数据 |
MethodMetadata factoryMethodMetadata | 所选工厂方法的元数据 |
ScannedGenericBeanDefinition
基于 ASM ClassReader 的 GenericBeanDefinition 类的扩展,支持通过 AnnotatedBeanDefinition 接口暴露注释元数据。这个类不会提前加载 bean 类。它从 .class 文件本身检索所有相关元数据,并使用 ASM ClassReader 进行解析。它在功能上等同于 AnnotatedGenericBeanDefinition (AnnotationMetadata),但是根据已扫描的 bean 类型与通过其他方式注册或检测的 bean 类型进行区分。
根 Bean 定义
RootBeanDefinition
- 根 bean 定义表示在运行时支持 Spring BeanFactory 中的特定 bean 的合并 bean 定义。它可能是从多个彼此继承的原始 bean 定义创建的,通常注册为 GenericBeanDefinition。根 bean 定义本质上是运行时的 “统一” bean 定义视图。
- 根 bean 定义还可以用于在配置阶段注册单个 bean 定义。然而,自 Spring2.5 以来,以编程方式注册 bean 定义的首选方法是 GenericBeanDefinition 类。GenericBeanDefinition 的优点是它允许动态定义父依赖关系,而不是像根 bean 定义那样对角色进行硬编码
字段 | 描述 |
BeanDefinitionHolder decoratedDefinition | bean 定义装饰的目标定义,带有名称和别名的 BeanDefinition的Holder |
AnnotationElement qualifiedElement | 指定 AnnotatedElement 定义限定符,以代替目标类或工厂方法 |
boolean stale | 确定是否需要重新合并定义 |
boolean allowCaching | 是否允许缓存,默认 true |
boolean isFactoryMethodUnique | 引用是否重载方法的工厂方法名,默认 false |
ResolvableType targetType | 目标类型 |
Class<?> resolvedTargetType | 缓存给定 bean 定义的确定 Class |
Boolean isFactoryBean | 缓存 bean 是否是工厂 bean |
ResolvableType factoryMethodReturnType | 缓存泛型工厂方法的返回类型 |
Method factoryMethodToIntrospect | 缓存用于内省的唯一候选工厂方法 |
Executable resolvedConstructorOrFactoryMethod | 缓存已解析的构造函数或工厂方法 |
boolean constructorArgumentsResolved | 将构造函数参数标记为已解析,默认 false |
Object[] resolvedConstructorArguments | 缓存完全解析的构造函数参数 |
Object[] preparedConstructorArguments | 缓存部分准备好的构造函数参数 |
boolean postProcessed | 表示已经应用了MergedBeanDefinitionPostProcessor,默认 false |
Boolean beforeInstantiationResolved | 指示已启动实例化前的后处理器 |
Set<Member> externallyManagedConfigMemebers | 外部管理的配置成员(标注 Autowired、Value、Resource 注解字段和方法) |
Set<String≫ externallyManagedInitMethods | 外部管理的I初始化方法集合( PostConstruct 注解标注的方法) |
Set<String> externallyManagedDestroyMethods | 外部管理的I销毁方法集合( PreDestroy 注解标注的方法) |
方法 | 描述 |
get/setDecoratedDefinition(BeanDefinitionHolder decoratedDefinition) | 获得/注册由此 bean 定义装饰的目标定义 |
get/setQualifiedElement(AnnotatedElement qualifiedElement | 返回/指定 AnnotatedElement 定义限定符,以代替目标类或工厂方法 |
getTargetType() | 如果已知(提前指定或在第一次实例化时解析),则返回此 bean 定义的目标类型 |
setTargetType() | 如果事先知道,则指定此 bean 定义的[包含泛型的]目标类型 |
getPreferredConstructors() | 如果有的话,确定用于默认构造的首选构造函数。如果需要,构造函数参数将自动装配 |
set[Non]uniqueFactoryMethodName(String name) | 指定一个引用[非]重载方法的工厂方法名 |
isFactoryMethod(Method candidate) | 检查给定的候选方法是否符合工厂方法的条件 |
get/setResolvedFactoryMethod(Method method) | 获取/为这个 bean 定义上的工厂方法设置一个已解析的 Java 方法 |
registerExternallyManaged ConfigMember/InitMethod/DestroyMethod | 注册外部管理的配置成员/初始化方法/销毁方法 |
isExternallyManaged ConfigMember/InitMethod/DestroyMethod | 是否是外部管理的配置成员/初始化方法/销毁方法 |
ConfigurationClassBeanDefinition
RootBeanDefinition 标记子类,用于表示 bean 定义是从配置类创建的,而不是任何其他配置源。 用于需要确定 bean 定义是否是在外部创建的 bean 覆盖情况。
字段 | 描述 |
final AnnotationMetadata metadata | 涉及的 bean 类的注解元数据 |
final MethodMetadata factoryMethodMetadata | 所选工厂方法的元数据 |
另一种方式构建 Bean 定义:BeanDefinitionBuilder
使用构建器模式构建 BeanDefinitions 的编程方法。主要用于实现 Spring 2.0 名称空间处理程序时
字段 | 描述 |
static BeanDefinitionBuilder root/generic/childBeanDefinition() | 通过以 root 或者 generic 以及 child 开头的静态方法构建不同类型的 Bean 定义 |
set/add*() | 通过 set 或者 add 方法添加 Bean 属性 |
getRawBeanDefinition() | 以原始(未验证的)形式返回当前 BeanDefinition 对象 |
getBeanDefinition() | 验证并返回创建的 BeanDefinition 对象 |