本文搬自于Spring(四)核心容器 - BeanDefinition 解析
现如今,我们一般获取对象的方式有两种,一种是手动直接 new;另一种是交给 Spring 管理,Spring 将管理的对象称之为 Bean,容器会先实例化 Bean,然后自动注入,实例化的过程就需要依赖 BeanDefinition。
BeanDefinition 用于保存 Bean 的相关信息,包括属性、构造方法参数、依赖的 Bean 名称及是否单例、延迟加载等,它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean。
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();
}
AnnotatedBeanDefinition 是 BeanDefinition 子接口之一,该接口扩展了 BeanDefinition 的功能,其用来操作注解元数据。一般情况下,通过注解方式得到的 Bean(@Component、@Bean),其 BeanDefinition 类型都是该接口的实现类。
public interface AnnotatedBeanDefinition extends BeanDefinition {
// 获得当前 Bean 的注解元数据
//AnnotationMetadata:主要对 Bean 的注解信息进行操作,如:获取当前 Bean 标注的所有注解、判断是否包含指定注解。
AnnotationMetadata getMetadata();
// 获得当前 Bean 的工厂方法上的元数据
//MethodMetadata:方法的元数据类。提供获取方法名称、此方法所属类的全类名、是否是抽象方法、判断是否是静态方法、判断是否是final方法等。
MethodMetadata getFactoryMethodMetadata();
}
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。
该类继承自 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;
...
}
最后,我们来做个总结。BeanDefinition 主要是用来描述 Bean,其存储了 Bean 的相关信息,Spring 实例化 Bean 时需读取该 Bean 对应的 BeanDefinition。BeanDefinition 整体可以分为两类,一类是描述通用的 Bean,还有一类是描述注解形式的 Bean。一般前者在 XML 时期定义