SpringBean重要对象之BeanDefinition的介绍

前言

本文搬自于Spring(四)核心容器 - BeanDefinition 解析

现如今,我们一般获取对象的方式有两种,一种是手动直接 new;另一种是交给 Spring 管理,Spring 将管理的对象称之为 Bean,容器会先实例化 Bean,然后自动注入,实例化的过程就需要依赖 BeanDefinition。

BeanDefinition 用于保存 Bean 的相关信息,包括属性、构造方法参数、依赖的 Bean 名称及是否单例、延迟加载等,它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean。

1、BeanDefinition的继承体系

在这里插入图片描述

BeanDefinition描述一个bean实例,它具有属性值,构造函数参数值,以及具体实施


public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

    // 单例、原型标识符
	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;//singleton
	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;//prototype

	// 标识 Bean 的类别,分别对应 用户定义的 Bean、来源于配置文件的 Bean、Spring 内部的 Bean
	int ROLE_APPLICATION = 0;
	int ROLE_SUPPORT = 1;
	int ROLE_INFRASTRUCTURE = 2;


	// 设置、返回 Bean 的父类名称
	void setParentName(@Nullable String parentName);
	String getParentName();

    // 设置、返回 Bean 的 className
	void setBeanClassName(@Nullable String beanClassName);
	String getBeanClassName();

    // 设置、返回 Bean 的作用域
	void setScope(@Nullable String scope);
	String getScope();

    // 设置、返回 Bean 是否懒加载
	void setLazyInit(boolean lazyInit);
	boolean isLazyInit();
	
	// 设置、返回当前 Bean 所依赖的其它 Bean 名称。
	void setDependsOn(@Nullable String... dependsOn);
	String[] getDependsOn();
	
	// 设置、返回 Bean 是否可以自动注入。只对 @Autowired 注解有效
	void setAutowireCandidate(boolean autowireCandidate);
	boolean isAutowireCandidate();
	
	// 设置、返回当前 Bean 是否为主要候选 Bean 。
	// 当同一个接口有多个实现类时,通过该属性来配置某个 Bean 为主候选 Bean。
	void setPrimary(boolean primary);
	boolean isPrimary();

    // 设置、返回创建该 Bean 的工厂类。
	void setFactoryBeanName(@Nullable String factoryBeanName);
	String getFactoryBeanName();
	
	// 设置、返回创建该 Bean 的工厂方法
	void setFactoryMethodName(@Nullable String factoryMethodName);
	String getFactoryMethodName();
	
	// 返回该 Bean 构造方法参数值,用于后面的属性赋值
	ConstructorArgumentValues getConstructorArgumentValues();

   // 返回该 Bean所有属性的值,用于后面的属性赋值
	MutablePropertyValues getPropertyValues();

    // 返回该 Bean 是否是单例、是否是非单例、是否是抽象的
	boolean isSingleton();
	boolean isPrototype();
	boolean isAbstract(); //

    // 返回 Bean 的类别。类别对应上面的三个属性值。
	int getRole();

}

2、AnnotatedBeanDefinition

AnnotatedBeanDefinition 是 BeanDefinition 子接口之一,该接口扩展了 BeanDefinition 的功能,其用来操作注解元数据。一般情况下,通过注解方式得到的 Bean(@Component、@Bean),其 BeanDefinition 类型都是该接口的实现类。

public interface AnnotatedBeanDefinition extends BeanDefinition {

	// 获得当前 Bean 的注解元数据
	//AnnotationMetadata:主要对 Bean 的注解信息进行操作,如:获取当前 Bean 标注的所有注解、判断是否包含指定注解。
	AnnotationMetadata getMetadata();

	// 获得当前 Bean 的工厂方法上的元数据
	//MethodMetadata:方法的元数据类。提供获取方法名称、此方法所属类的全类名、是否是抽象方法、判断是否是静态方法、判断是否是final方法等。
	MethodMetadata getFactoryMethodMetadata();
}
3、AbstractBeanDefinition

AbstractBeanDefinition 是 BeanDefinition 的子抽象类,也是其他 BeanDefinition 类型的基类,其实现了接口中定义的一系列操作方法,并定义了一系列的常量属性,这些常量会直接影响到 Spring 实例化 Bean 时的策略。核心属性如下。

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
		implements BeanDefinition, Cloneable {

    // 默认的 SCOPE,默认是单例
	public static final String SCOPE_DEFAULT = "";

	// 不进行自动装配
	public static final int AUTOWIRE_NO = AutowireCapableBeanFactory.AUTOWIRE_NO;
    // 根据 Bean 的名字进行自动装配,byName
	public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
	// 根据 Bean 的类型进行自动装配,byType
	public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
	// 根据构造器进行自动装配
	public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
	// 首先尝试按构造器自动装配。如果失败,再尝试使用 byType 进行自动装配。(Spring 3.0 之后已废除)
	public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;

    // 通过依赖检查来查看 Bean 的每个属性是否都设置完成
    // 以下常量分别对应:不检查、对依赖对象检查、对基本类型,字符串和集合进行检查、对全部属性进行检查
	public static final int DEPENDENCY_CHECK_NONE = 0;
	public static final int DEPENDENCY_CHECK_OBJECTS = 1;
	public static final int DEPENDENCY_CHECK_SIMPLE = 2;
	public static final int DEPENDENCY_CHECK_ALL = 3;

	// 关闭应用上下文时需调用的方法名称
	public static final String INFER_METHOD = "(inferred)";

    // 存放 Bean 的 Class 对象
	private volatile Object beanClass;

	// Bean 的作用范围
	private String scope = SCOPE_DEFAULT;

    // 非抽象
	private boolean abstractFlag = false;
	// 非延迟加载
	private boolean lazyInit = false;
    // 默认不自动装配
	private int autowireMode = AUTOWIRE_NO;
    // 默认不依赖检查
	private int dependencyCheck = DEPENDENCY_CHECK_NONE;

	// 依赖的 Bean 列表
	private String[] dependsOn;

    // 可以作为自动装配的候选者,意味着可以自动装配到其他 Bean 的某个属性中
	private boolean autowireCandidate = true;
    
	// 创建当前 Bean 实例工厂类名称
	private String factoryBeanName;
    // 创建当前 Bean 实例工厂类中方法名称
	private String factoryMethodName;

	// 存储构造方法的参数
	private ConstructorArgumentValues constructorArgumentValues;
    // 存储 Bean 属性名称以及对应的值
	private MutablePropertyValues propertyValues;
    // 存储被覆盖的方法信息
	private MethodOverrides methodOverrides;

	// init、destroy 方法名称
	private String initMethodName;
	private String destroyMethodName;

    // 是否执行 init 和 destroy 方法
	private boolean enforceInitMethod = true;
	private boolean enforceDestroyMethod = true;

    // Bean 是否是用户定义的而不是应用程序本身定义的
	private boolean synthetic = false;

    // Bean 的身份类别,默认是用户定义的 Bean
	private int role = BeanDefinition.ROLE_APPLICATION;

	// Bean 的描述信息
	private String description;

	// Bean 定义的资源
	private Resource resource;
	
	...
}

以上是 AbstractBeanDefinition 中定义的一些常量和属性,该类中还有一部分是操作这些属性的 set 和 get 方法,这些方法都由子类来操作,且应用程序中真正使用的也是这些子类 BeanDefinition。

先来看 AbstractBeanDefinition 直接实现类:RootBeanDefinition、GenericBeanDefinition、ChildBeanDefinition。

4、RootBeanDefinition

该类继承自 AbstractBeanDefinition,它可以单独作为一个 BeanDefinition,也可以作为其他 BeanDefinition 的父类。

RootBeanDefinition 在 AbstractBeanDefinition 的基础上定义了更多属性。

public class RootBeanDefinition extends AbstractBeanDefinition {

    // BeanDefinitionHolder 存储 Bean 的名称、别名、BeanDefinition
	private BeanDefinitionHolder decoratedDefinition;

	// AnnotatedElement 是java反射包的接口,通过它可以查看 Bean 的注解信息
	private AnnotatedElement qualifiedElement;

    // 允许缓存
	boolean allowCaching = true;
    
    // 工厂方法是否唯一
	boolean isFactoryMethodUnique = false;

	// 封装了 java.lang.reflect.Type,提供了泛型相关的操作
	volatile ResolvableType targetType;

	// 缓存 Class,表示 RootBeanDefinition 存储哪个类的信息
	volatile Class<?> resolvedTargetType;

	// 缓存工厂方法的返回类型
	volatile ResolvableType factoryMethodReturnType;

	// 这是以下四个构造方法字段的通用锁
	final Object constructorArgumentLock = new Object();
	// 用于缓存已解析的构造方法或工厂方法
	Executable resolvedConstructorOrFactoryMethod;
	// 将构造方法参数标记为已解析
	boolean constructorArgumentsResolved = false;
	// 用于缓存完全解析的构造方法参数
	Object[] resolvedConstructorArguments;
	// 缓存待解析的构造方法参数
	Object[] preparedConstructorArguments;

	// 这是以下两个后处理字段的通用锁
	final Object postProcessingLock = new Object();
	// 表明是否被 MergedBeanDefinitionPostProcessor 处理过
	boolean postProcessed = false;
	// 在生成代理的时候会使用,表明是否已经生成代理
	volatile Boolean beforeInstantiationResolved;

	// 实际缓存的类型是 Constructor、Field、Method 类型
	private Set<Member> externallyManagedConfigMembers;

	// InitializingBean中 的 init 回调函数名 afterPropertiesSet 会在这里记录,以便进行生命周期回调
	private Set<String> externallyManagedInitMethods;

	// DisposableBean 的 destroy 回调函数名 destroy 会在这里记录,以便进生命周期回调
	private Set<String> externallyManagedDestroyMethods;

    ...
}
5、总结

最后,我们来做个总结。BeanDefinition 主要是用来描述 Bean,其存储了 Bean 的相关信息,Spring 实例化 Bean 时需读取该 Bean 对应的 BeanDefinition。BeanDefinition 整体可以分为两类,一类是描述通用的 Bean,还有一类是描述注解形式的 Bean。一般前者在 XML 时期定义 <bean‘> 标签以及在 Spring 内部使用较多,而现今我们大都使用后者,通过注解形式加载 Bean。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值