Spring IOC 源码解析(四) BeanDefinition

一.前言

BeanDefinition是配置文件<bean>元素标签在容器中地内部表示。<bean>元素标签拥有class、scope、lazy-init等配置属性,BeanDefinition 则提供了相应地beanClass、scope、lazyInit类属性,BeanDefinition 就像<bean>中镜中人,二者是一一对应地

来看一下整体的类结构图,我们将从上往下依次讲解
在这里插入图片描述

二.BeanDefinition 结构分解

2.1 AttributeAccessor

定义一个通用协定的接口,用于在任意对象之间附加和访问元数据.

主要功能:

  1. 返回所有属性的名称
  2. 获取指定属性名的值
  3. 判断是否包含指定属性名
  4. 删除指定的属性并返回其值。
  5. 设置指定属性的值

2.2 AttributeAccessorSupport

实现 AttributeAccessors 接口,提供所有方法的基本实现。由子类扩展。

如果子类和所有属性值都是Serializable,则可序列化。

AttributeAccessorSupport 中拥有一个 LinkedHashMap 类型的 map (attributes).
存放属性; key : 属性名, value : 属性值.

扩展功能:

  1. 拥有 AttributeAccessors 所有功能实现
  2. 将属性从提供的 AttributeAccessor 复制到此访问器。

注意:该类重写了 equals 和 hashCode 方法

2.3 BeanMetadataElement

由携带配置源对象的bean元数据元素实现的接口。

唯一方法:

  • 返回此元数据元素的配置源Object(可以为null)。

2.4 BeanDefinition

BeanDefinition 描述了一个 bean 实例,它具有属性值,构造函数参数值以及具体实现提供的更多信息。

这只是一个最小的接口:主要目的是允许BeanFactoryPostProcessor(如PropertyPlaceholderConfigurer)内省和修改属性值以及 Bean 其他元数据。

主要功能:

  1. 返回 BeanDefinition 的类名
  2. 返回此 bean 的构造函数参数值
  3. 返回此 bean 依赖的 bean 名称列表
  4. 返回此 BeanDefinition 的可读描述
  5. 返回 destroy 方法的名称
  6. 返回 factoryBean 名称(如果有)
  7. 返回工厂方法名
  8. 返回初始化方法名称
  9. 返回原始的 BeanDefinition, 如果没有返回 null
  10. 返回此 BeanDefinition 的父 BeanDefinition 名称(如果有)
  11. 返回要应用于 bean 的新实例的属性值
  12. 返回此 BeanDefinition 来源的资源描述符(为了在出现错误时显示上下文)
  13. 获取此 BeanDefinition 的角色提示。
  14. 返回此 bean 的当前目标作用域的名称,如果尚未知,则返回null。
  15. 判断 BeanDefinition 的构造函数是否有参数值
  16. 判断是否为 BeanDefinition 定义了属性值
  17. 判断此 bean 是否是抽象类,即不实例化
  18. 判断此 bean 是否可以自动装配到其他bean。
  19. 判断此 bean 是否是懒加载(lazyInit=true)
  20. 返回此 bean 是否是主要的自动装配候选者(@Primary)。
  21. 判断是 单例 bean 还是原型 bean
  22. 以及一些设置以上属性的 set 方法

2.5 BeanMetadataAttributeAccessor

AttributeAccessorSupport 的扩展,将属性保存为 BeanMetadataAttribute 对象,以便跟踪定义源。

主要功能:

  1. 添加 BeanMetadataAttribute 到 AttributeAccessorSupport 的 map 中进行管理
  2. 根据指定属性名获取 BeanMetadataAttribute 的属性值
  3. 删除指定属性名的属性,并返回删除的属性值
  4. 设置属性值,将 value 封装为 BeanMetadataAttribute,存入到 AttributeAccessorSupport 的 map 中
  5. 实现 BeanMetadataElement 接口,设置和获取 BeanMetadataAttributeAccessor 的唯一字段 source(Obejct 类型)

BeanMetadataAttribute 是一个简单的 POJO,我们来看一下储存的 BeanMetadataAttribute 都有哪些属性:

public class BeanMetadataAttribute implements BeanMetadataElement {

	private final String name;

	private final Object value;

	private Object source;
	
	// set ,get ,equals ,hashCode ,toString
}

可以看到 BeanMetadataAttribute 也实现了 BeanMetadataElement 方法的唯一方法 getSource;

2.6 AbstractBeanDefinition

具体的,成熟的 BeanDefinition 类的基类,提取出 GenericBeanDefinition,RootBeanDefinition 和ChildBeanDefinition 的公共属性(这三个类是 AbstractBeanDefinition 的实现子类)。

autowire 常量与 AutowireCapableBeanFactory 接口中定义的常量匹配。

主要功能:

  1. 实现 BeanDefinition 接口的所有方法
  2. 克隆此 BeanDefinition
  3. 返回有关 IoC 容器要覆盖的方法的信息
  4. 返回原始的 BeanDefinition
  5. 返回此 bean 的属性值
  6. 返回此 BeanDefinition 来自的资源文件 Resource
  7. 验证并准备给定的方法覆盖。
  8. 覆盖此 BeanDefinition 中的设置(可能是来自父子继承关系的覆盖)
  9. 通过指定的 classLoader 解析 bean 的 class 对象
  10. 验证此 BeanDefinition

2.7 RootBeanDefinition

我们都知道 <bean>可以设置父<bean> ,而父<bean>在 spring 中的存储方式就是 RootBeanDefinition,

RootBeanDefinition, 表示合并的 BeanDefinition,它可能是从多个原始 BeanDefinition 创建的,这些定义相互继承,通常注册为 GenericBeanDefinitions。RootBeanDefinition 本质上是运行时的“统一” BeanDefinition 视图.

RootBeanDefinition 也可用于在配置阶段注册单个 BeanDefinition。但是,从Spring 2.5开始,以编程方式注册 BeanDefinition 的首选方法是 GenericBeanDefinition 类。 GenericBeanDefinition 的优点是它允许动态定义父依赖关系,而不是将角色“硬编码”为 RootBeanDefinition。

主要功能:

  1. 确定用于默认构造的首选构造函数
  2. 将已解析的工厂方法作为 java 方法返回对象
  3. 判断给定方法(Method 对象)是否是工厂方法
  4. 设置父 BeanName

2.8 ChildBeanDefinition

通过 2.7 我们知道 ,该 BeanDefinition 是具有父<bean><bean> 在 spring ioc 中的具体实现.

子 BeanDefinition 将从父级继承构造函数参数值,属性值和方法覆盖,并具有添加新值的选项。如果指定了init方法,destroy 方法和/或静态工厂方法,它们将覆盖相应的父设置。其余设置将始终从子定义中获取:取决于,autowire模式,依赖性检查,单例,惰性初始化。

从Spring 2.5开始,以编程方式注册 BeanDefinition 的首选方法是 GenericBeanDefinition 类,它允许通过GenericBeanDefinition.setParentName(java.lang.String)方法动态定义父依赖项。这有效地取代了大多数用例的ChildBeanDefinition类。

主要功能:
1.设置父 bean
2.克隆此 BeanDefinition
3.验证 BeanDefinition

2.9 GenericBeanDefinition

GenericBeanDefinition 是用于标准 BeanDefinition 目的一站式。与任何bean定义一样,它允许指定类以及可选的构造函数参数值和属性值。此外,可以通过“parentName”属性灵活配置从父bean定义派生。

通常,使用此 GenericBeanDefinition 类来注册用户可见的 BeanDefinition(post-processor可以操作,甚至可能重新配置父名称)。使用 RootBeanDefinition / ChildBeanDefinition,其中 父/子 关系是预先写死的.

主要功能:
1.设置父 bean
2.克隆此 BeanDefinition

2.10 AnnotatedBeanDefinition

扩展 BeanDefinition 的接口,暴露 beanClass 的注解元数据 AnnotationMetadata,不需要加载类

主要功能:

  1. 获取此 BeanDefinition 工厂方法的元数据(如果有)。
  2. 获取此 BeanDefinition 的 bean 类的注释元数据(以及基本类元数据)。

2.11 AnnotatedGenericBeanDefinition

扩展 GenericBeanDefinition ,添加暴露注解元数据的支持

这个是 GenericBeanDefinition 变体主要用于测试,希望在带注解的 BeanDefinition 上操作,例如 Spring的组件扫描支持中的策略实现(其中默认定义类是 ScannedGenericBeanDefinition,它还实现AnnotatedBeanDefinition接口)。

原文:

This GenericBeanDefinition variant is mainly useful for testing code that expects to operate on an AnnotatedBeanDefinition, for example strategy implementations in Spring’s component scanning support (where the default definition class is ScannedGenericBeanDefinition, which also implements the AnnotatedBeanDefinition interface).

主要功能:

  1. 在 GenericBeanDefinition基础上,实现了 AnnotatedBeanDefinition 接口具有的功能,暴露注解元数据的功能

2.12 ScannedGenericBeanDefinition

GenericBeanDefinition类的扩展,基于 ASM ClassReader,支持通过 AnnotatedBeanDefinition 接口公开的注释元数据。

这个类没有提前加载 beanClass, 它从“.class”文件本身检索所有相关元数据,并使用 ASM ClassReader 进行解析。它在功能上等同于 AnnotatedGenericBeanDefinition(AnnotationMetadata),但按已扫描的bean 类型与以其他方式注册或检测的 bean 类型进行区分。

主要功能:
1.和 AnnotatedGenericBeanDefinition 一样

2.13 ConfigurationClassBeanDefinitionReader 内部类 ConfigurationClassBeanDefinition

private static class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition

RootBeanDefinition 标记子类,用于表示从配置类创建 BeanDefinition ,而不是任何其他配置源。用于bean重写的情况,需要确定 BeanDefinition 是否是在外部创建的。

主要功能:
1.在 RootBeanDefinition 基础上,实现了 AnnotatedBeanDefinition 接口具有的功能,暴露注解元数据的功能

Spring IOC 源码解析(五) ResourceLoader

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值