介绍
在SpringIOC流程分析过程中,对于Bean的控制反转创建过程一定离不开BeanDefinition.虽然它是接口,基于它有
AbstractBeanDefinition
,RootBeanDefinition
,GenericBeanDefinition
等各种实现.创建Bean的过程也会将不同的BeanDefinition转成RootBeanDefinition来进行使用.
它经过Spring解析对应类或配置保存了该Bean的各种信息,例如该Bean的类型、是否是抽象类、作用域、该Bean的初始化,销毁方法、需要注入那些Bean等.
可以理解为存放Bean创建所需的材料列表.然后Spring根据创建说明来进行Bean的创建操作
创建说明包含材料获取以及生成.BeanDefinitionRegistry
负责BeanDefinition注册即材料获取环节,BeanFactory
负责Bean的创建环节,管控Bean的部分生命周期.最后交由Spring容器调度
例外
通过beanFactory.registerSingleton方法手动加入Bean是不会用到BeanDefinition的,这里是将现有Bean加入BeanFactory中.
例如:bf.registerSingleton(WebApplicationContext.SERVLET_CONTEXT_BEAN_NAME, servletContext);
BeanDefinition接口
/**
* 该接口主要定义一些基础Bean元数据信息属性值以及基础属性获取方法
*/
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 定义单例/多例的常量值
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
// 定义Bean的作用角色.
// 0表示应用级.1表示配置拓展支撑级.2表示内部构造级。0,1为自定义级别
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
// 下面是可修改的定义属性
// 指定父类
void setParentName(@Nullable String parentName);
@Nullable
String getParentName();
// 当前类
void setBeanClassName(@Nullable String beanClassName);
@Nullable
String getBeanClassName();
// 指定作用域.SCOPE_SINGLETON或者SCOPE_PROTOTYPE两种
void setScope(@Nullable String scope);
@Nullable
String getScope();
// 指定是否懒加载
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
// 指定依赖对象列表
void setDependsOn(@Nullable String... dependsOn);
@Nullable
String[] getDependsOn();
// 是否支持自动注入.支持的才可以被注入到其他地方.只支持@Autorire方式判断
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
// 当多Bean类型重复是否是注入Bean的首选
void setPrimary(boolean primary);
boolean isPrimary();
// 设置该Bean的工厂Bean(专门创建该Bean的工厂).
void setFactoryBeanName(@Nullable String factoryBeanName);
@Nullable
String getFactoryBeanName();
// 设置工厂方法.
void setFactoryMethodName(@Nullable String factoryMethodName);
@Nullable
String getFactoryMethodName();
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
// 该Bean的属性集合
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
// 初始化执行方法. @PostConstruct注解标注的/配置文件指定的.
void setInitMethodName(@Nullable String initMethodName);
@Nullable
String getInitMethodName();
// 销毁执行方法 @PreDestroy注解标注的/配置文件指定的.
// 也可以@Bean(initMethod = "init",destroyMethod = "destory")指定
void setDestroyMethodName(@Nullable String destroyMethodName);
@Nullable
String getDestroyMethodName();
// 设置该Bean角色
void setRole(int role);
int getRole();
//
void setDescription(@Nullable String description);
@Nullable
String getDescription();
// Read-only attributes
// 返回该类解析过后的元信息
ResolvableType getResolvableType();
// 是否是单例
boolean isSingleton();
// 是否是多例
boolean isPrototype();
// 是否是抽象类
boolean isAbstract();
@Nullable
String getResourceDescription();
// 返回最原始BeanDefinition.当该Bean有被其他postProcessor处理过(代理修饰).则该方法可以返回最原先的BeanDefinition
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
子接口AnnotatedBeanDefinition定义访问目标类注解信息接口
// 该类意思是无需加载目标类即可获取目标类的信息
public interface AnnotatedBeanDefinition extends BeanDefinition {
// 获取类上的注解信息
AnnotationMetadata getMetadata();
// 如果该Bean定义了工厂方法,则返回工厂方法元数据信息
// 名字、返回类型、是否抽象、是否是静态的、是否不可继承、是否可重写
@Nullable
MethodMetadata getFactoryMethodMetadata();
}
AbstractBeanDefinition定义了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;
public static final int AUTOWIRE_BY_NAME = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
public static final int AUTOWIRE_BY_TYPE = AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE;
public static final int AUTOWIRE_CONSTRUCTOR = AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR;
@Deprecated
public static final int AUTOWIRE_AUTODETECT = AutowireCapableBeanFactory.AUTOWIRE_AUTODETECT;
//检查依赖是否合法,在本类中,默认不进行依赖检查
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; //对所有属性的依赖进行检查
//若Bean未指定销毁方法,容器应该尝试推断Bean的销毁方法的名字,目前来说,推断的销毁方法的名字一般为close或是shutdown
//(即未指定Bean的销毁方法,但是内部定义了名为close或是shutdown的方法,则容器推断其为销毁方法)
public static final String INFER_METHOD = "(inferred)";
//定义一些SpringIOC的默认属性信息
//Bean的class对象或是类的全限定名
@Nullable
private volatile Object beanClass;
//默认的scope是单例
@Nullable
private String scope = SCOPE_DEFAULT;
//默认不为抽象类
private boolean abstractFlag = false;
//默认不懒加载
private boolean lazyInit = false;
//默认是没有依赖注入的模式
private int autowireMode = AUTOWIRE_NO;
//默认不进行依赖检查
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
// @@DependsOn 默认没有依赖
@Nullable
private String[] dependsOn;
// 是否支持自动装配
// false时,容器在查找自动装配对象时,将不考虑该bean
private boolean autowireCandidate = true;
// 默认不是首选的
private boolean primary = false;
//存储该Bean依赖中使用@Qualifier标注的自动装配信息,多指定依赖的Bean名称.防止多个同类型Bean造成的NoUniqueBeanDefinitionException异常
private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>(0);
//我理解为通过这个函数的逻辑初始化Bean,而不是构造函数或是工厂方法(相当于自己去实例化,而不是交给Bean工厂)
@Nullable
private Supplier<?> instanceSupplier;
//是否允许访问非public方法和属性,应用于构造函数、工厂方法、init、destroy方法的解析 默认是true,表示啥都可以访问
private boolean nonPublicAccessAllowed = true;
// 是否以一种宽松的模式解析构造函数,默认为true(宽松和严格体现在类型匹配上)
private boolean lenientConstructorResolution = true;
//工厂类名(注意是String类型,不是Class类型) 对应bean属性factory-method
@Nullable
private String factoryBeanName;
//工厂方法名(注意是String类型,不是Method类型)
@Nullable
private String factoryMethodName;
//记录构造函数注入属性,对应bean属性constructor-arg
@Nullable
private ConstructorArgumentValues constructorArgumentValues;
//Bean属性的名称以及对应的值,这里不会存放构造函数相关的参数值,只会存放通过setter注入的依赖
@Nullable
private MutablePropertyValues propertyValues;
//方法重写的持有者,记录lookup-method、replaced-method元素 @Lookup等
@Nullable
private MethodOverrides methodOverrides;
//init函数的名字
@Nullable
private String initMethodName;
//destory函数的名字
@Nullable
private String destroyMethodName;
//是否执行init-method,程序设置
private boolean enforceInitMethod = true;
private boolean enforceDestroyMethod = true;
//是否是合成类(是不是应用自定义的,例如生成AOP代理时,会用到某些辅助类,这些辅助类不是应用自定义的,这个就是合成类)
//创建AOP时候为true
private boolean synthetic = false;
//Bean的角色,为用户自定义Bean
private int role = BeanDefinition.ROLE_APPLICATION;
// Bean的描述信息
@Nullable
private String description;
//the resource that this bean definition came from
// 类的源信息(加载一个类可能是一个文件/网络地址)
@Nullable
private Resource resource;
// 其实就是给reource赋值了,使用了BeanDefinitionResource
public void setOriginatingBeanDefinition(BeanDefinition originatingBd) {
this.resource = new BeanDefinitionResource(originatingBd);
}
// 上面有赋值,所以get的时候就是返回上面set进来的值
public BeanDefinition getOriginatingBeanDefinition() {
return (this.resource instanceof BeanDefinitionResource ?
((BeanDefinitionResource) this.resource).getBeanDefinition() : null);
}
//克隆Bean的定义信息
@Override
public Object clone() {
return cloneBeanDefinition();
}
public abstract AbstractBeanDefinition cloneBeanDefinition();
}
RootBeanDefinition
生成Bean时会将不同的BeanDefinition合并成RootBeanDefinition.当某个类有父类会将父类的BeanDefinition合并进该类的BeanDefinition中.在AbstractBeanFactory.doGetBean方法中,也是Context.refresh的第十一步执行
public class RootBeanDefinition extends AbstractBeanDefinition {
//BeanDefinitionHolder存储有Bean的名称、别名、BeanDefinition
@Nullable
private BeanDefinitionHolder decoratedDefinition;
// AnnotatedElement 是java反射包的接口,通过它可以查看Bean的注解信息
@Nullable
private AnnotatedElement qualifiedElement;
//允许缓存
boolean allowCaching = true;
//从字面上理解:工厂方法是否唯一
boolean isFactoryMethodUnique = false;
//封装了java.lang.reflect.Type,提供了泛型相关的操作,具体请查看:
// ResolvableType 可以专题去了解一下子,虽然比较简单 但常见
@Nullable
volatile ResolvableType targetType;
//缓存class,表明RootBeanDefinition存储哪个类的信息
@Nullable
volatile Class<?> resolvedTargetType;
//缓存工厂方法的返回类型
@Nullable
volatile ResolvableType factoryMethodReturnType;
/** Common lock for the four constructor fields below */
final Object constructorArgumentLock = new Object();
//缓存已经解析的构造函数或是工厂方法,Executable是Method、Constructor类型的父类
@Nullable
Executable resolvedConstructorOrFactoryMethod;
//表明构造函数参数是否解析完毕
boolean constructorArgumentsResolved = false;
//缓存完全解析的构造函数参数
@Nullable
Object[] resolvedConstructorArguments;
//缓存待解析的构造函数参数,即还没有找到对应的实例,可以理解为还没有注入依赖的形参
@Nullable
Object[] preparedConstructorArguments;
/** Common lock for the two post-processing fields below */
final Object postProcessingLock = new Object();
//表明是否被MergedBeanDefinitionPostProcessor处理过
boolean postProcessed = false;
//在生成代理的时候会使用,表明是否已经生成代理
@Nullable
volatile Boolean beforeInstantiationResolved;
//实际缓存的类型是Constructor、Field、Method类型
@Nullable
private Set<Member> externallyManagedConfigMembers;
//InitializingBean中的init回调函数名——afterPropertiesSet会在这里记录,以便进行生命周期回调
@Nullable
private Set<String> externallyManagedInitMethods;
//DisposableBean的destroy回调函数名——destroy会在这里记录,以便进行生命周期回调
@Nullable
private Set<String> externallyManagedDestroyMethods;
}
AnnotatedGenericBeanDefinition
AnnotatedGenericBeanDefinition只能用于已经被注册或被扫描到的类
public static void main(String[] args) {
AnnotatedBeanDefinition beanDefinition = new AnnotatedGenericBeanDefinition(RootConfig.class);
// 获取注解方式便捷
Set<String> annotationTypes = beanDefinition.getMetadata().getAnnotationTypes();
System.out.println(annotationTypes); //[org.springframework.context.annotation.ComponentScan, org.springframework.context.annotation.Configuration]
System.out.println(beanDefinition.isSingleton()); //true
System.out.println(beanDefinition.getBeanClassName()); //com.config.RootConfig
}
ConfigurationClassBeanDefinition
是ConfigurationClassBeanDefinitionReader的一个私有的静态内部类:这个类负责将@Bean注解的方法转换为对应的ConfigurationClassBeanDefinition类(非常的重要),直接继承自RootBeanDefinition
最后
Spring初始化时,会用
GenericBeanDefinition
或是ConfigurationClassBeanDefinition
(用@Bean注解注释的类)存储用户自定义的Bean,在初始化Bean时,又会将其转换为RootBeanDefinition