BeanDefinition是什么
BeanDefinition是Spring用来保存关于Bean定义信息的。在Spring中,我们可以定义Bean的各种属性,生命周期,初始化等,而且不仅可以使用xml配置,还可以使用注解配置,这些配置最终都会保存在BeanDefinition对象中,Spring后续关于Bean的流程都是依据BeanDefinition展开的。
BeanDefinition整体架构
如上图所示,BeanDefinition接口继承自两个接口:BeanMetadataElement和AttributeAccessor。
而且BeanDefinition的实现类众多,包括:
- RootBeanDefinition
- ChildBeanDefinition
- ClassDerivedBeanDefinition
- GenericBeanDefinition
- AnnotatedGenericBeanDefinition
- ScannedGenericBeanDefinition
- ConfigurationClassBeanDefinition
下面我们就从基本接口定义到实现类逐个讲解。
BeanMetadataElement
该接口的定义很简单,就一个方法,用于获取Bean的源对象。
public interface BeanMetadataElement {
@Nullable
Object getSource();
}
AttributeAccessor
该接口主要定义了对对象元数据访问接口。
public interface AttributeAccessor {
void setAttribute(String name, @Nullable Object value);
@Nullable
Object getAttribute(String name);
@Nullable
Object removeAttribute(String name);
boolean hasAttribute(String name);
String[] attributeNames();
}
BeanDefinition
该接口是BeanDefinition的顶级接口,定义了一些要作为一个BeanDefinition需要实现的最基本的方法。
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// spring中bean的scope默认是singleton,即单例的
String SCOPE_SINGLETON = "singleton";
// spring中bean的scope如果是prototype,代表该bean是多例的
String SCOPE_PROTOTYPE = "prototype";
// 代表该bean是用户定义的
int ROLE_APPLICATION = 0;
// 代表该bean是某些配置的支撑部分
int ROLE_SUPPORT = 1;
// 代表该bean是spring内部定义的
int ROLE_INFRASTRUCTURE = 2;
// 设置该bean的父类名
void setParentName(@Nullable String parentName);
@Nullable
String getParentName();
// 设置该bean的全类名
void setBeanClassName(@Nullable String beanClassName);
@Nullable
String getBeanClassName();
// 设置该bean的作用域,singleton,prototyp
void setScope(@Nullable String scope);
@Nullable
String getScope();
// 设置该bean是否懒加载,如果设置了懒加载,该bean在启动的时候不会创建,在第一次使用的时候才会创建
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
// 设置该bean的依赖bean,可以控制bean创建的先后顺序
void setDependsOn(@Nullable String... dependsOn);
@Nullable
String[] getDependsOn();
// 设置该bean是否自动装配
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
// 设置该bean是否是首选,如果设置为首选,在spring根据条件查找到多个符合条件的bean时,会返回首选bean
void setPrimary(boolean primary);
boolean isPrimary();
// 设置FactoryBean名称,FactoryBean也是一个bean,它可以用来控制bean的生成
void setFactoryBeanName(@Nullable String factoryBeanName);
@Nullable
String getFactoryBeanName();
// 设置FactoryMethod的名称
// 如果该bean是一个工厂bean,通过设置的FacotoryMethodName方法可以获取该工厂bean生成的bean
void setFactoryMethodName(@Nullable String factoryMethodName);
@Nullable
String getFactoryMethodName();
// 获取该bean构造方法参数
ConstructorArgumentValues getConstructorArgumentValues();
// 判断该bean构造方法是否有参数
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
// 获取该bean属性集合
MutablePropertyValues getPropertyValues();
// 判断该bean是否有属性
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
// 判断该bean是否是单例的
boolean isSingleton();
// 判断该bean是否是多例的
boolean isPrototype();
// 判断该bean是否是抽象的,抽象的不能实例化
boolean isAbstract();
// 获取该bean的角色,ROLE_APPLICATION,ROLE_SUPPORT,ROLE_INFRASTRUCTURE
int getRole();
// 获取该bean的描述信息
@Nullable
String getDescription();
// 获取该bean的资源描述信息
@Nullable
String getResourceDescription();
// 获取该bean的原始bean定义,如果当前beanDefinition是一个代理对象,那么可以通过该方法获取原始的beanDefinition
@Nullable
BeanDefinition getOriginatingBeanDefinition();
}
AttributeAccessorSupport
该类是AttributeAccessor的抽象实现类,定义了一个Map用于保存属性信息,作为AttributeAccessor接口的一个默认接口实现。
public abstract class AttributeAccessorSupport implements AttributeAccessor, Serializable {
/** Map with String keys and Object values */
private final Map<String, Object> attributes = new LinkedHashMap<>();
@Override
public void setAttribute(String name, @Nullable Object value) {
Assert.notNull(name, "Name must not be null");
if (value != null) {
this.attributes.put(name, value);
}
else {
removeAttribute(name);
}
}
@Override
@Nullable
public Object getAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.get(name);
}
@Override
@Nullable
public Object removeAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.remove(name);
}
@Override
public boolean hasAttribute(String name) {
Assert.notNull(name, "Name must not be null");
return this.attributes.containsKey(name);
}
@Override
public String[] attributeNames() {
return StringUtils.toStringArray(this.attributes.keySet());
}
... // 忽略其它代码
}
BeanMetadataAttributeAccessor
该类继承了AttributeAccessorSupport并实现了BeanMetadataElement接口,其中重写了AttributeAccessorSupport中的部分接口。
public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport implements BeanMetadataElement {
@Nullable
private Object source;
public void setSource(@Nullable Object source) {
this.source = source;
}
@Override
@Nullable
public Object getSource() {
return this.source;
}
public void addMetadataAttribute(BeanMetadataAttribute attribute) {
super.setAttribute(attribute.getName(), attribute);
}
@Nullable
public BeanMetadataAttribute getMetadataAttribute(String name) {
return (BeanMetadataAttribute) super.getAttribute(name);
}
@Override
public void setAttribute(String name, @Nullable Object value) {
super.setAttribute(name, new BeanMetadataAttribute(name, value));
}
@Override
@Nullable
public Object getAttribute(String name) {
BeanMetadataAttribute attribute = (BeanMetadataAttribute) super.getAttribute(name);
return (attribute != null ? attribute.getValue() : null);
}
@Override
@Nullable
public Object removeAttribute(String name) {
BeanMetadataAttribute attribute = (BeanMetadataAttribute) super.removeAttribute(name);
return (attribute != null ? attribute.getValue() : null);
}
}
AbstractBeanDefinition
该类是bean定义的抽象类,实现了一些通用逻辑,定义了一些字段用于标识bean的各种情况。
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
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;
public static final String INFER_METHOD = "(inferred)";
// 用于保存bean的class对象
@Nullable
private volatile Object beanClass;
// 默认scope为"", 但是下面方法判断中,如果scope是""代表是单例的
@Nullable
private String scope = SCOPE_DEFAULT;
// 默认当前bean不是抽象的
private boolean abstractFlag = false;
// 默认当前bean不是懒加载的
private boolean lazyInit = false;
// 默认注入默认为不自动注入
private int autowireMode = AUTOWIRE_NO;
// 默认不进行依赖检查(Spring3.0之后弃用这个属性)
private int dependencyCheck = DEPENDENCY_CHECK_NONE;
// 用于保存当前的bean创建前,必须先创建哪些bean
@Nullable
private String[] dependsOn;
// 如果设置为false, 容器在自动装配对象的时候,不会将该bean作为其他bean依赖的bean,但是该bean依赖的bean
// 还是能够自动装配进来的
private boolean autowireCandidate = true;
// 当发生自动装配的时候,假如某个bean会发现多个,那么标注了primary为true的首先被注入
private boolean primary = false;
private final Map<String, AutowireCandidateQualifier> qualifiers = new LinkedHashMap<>();
@Nullable
private Supplier<?> instanceSupplier;
// 默认允许访问非public的构造方法
private boolean nonPublicAccessAllowed = true;
// 默认构造函数使用宽松模式构造的方式
// 在大部分情况下都是使用宽松模式,即使多个构造函数的参数数量相同、类型存在父子类、接口实现类关系也能正常创建bean
private boolean lenientConstructorResolution = true;
// 假如是通过@Configuration的@Bean的方式扫描进来的组件,那么该属性用于保存我们的是由哪个配置类
@Nullable
private String factoryBeanName;
// 用于保存我们的标注了@Bean的方法名称或者xml配置中配置的factory-method
@Nullable
private String factoryMethodName;
// 保存了构造参数的值
@Nullable
private ConstructorArgumentValues constructorArgumentValues;
// 保存了普通属性的集合
@Nullable
private MutablePropertyValues propertyValues;
// 保存了重写属性的集合,look-method 和replace-method
@Nullable
private MethodOverrides methodOverrides;
// 保存了配置的初始化方法名,比如xml中配置的init-method
@Nullable
private String initMethodName;
// 保存了配置的销毁方法名,比如xml中配置的destory-method
@Nullable
private String destroyMethodName;
// 是否执行 init-method 方法
private boolean enforceInitMethod = true;
// 是否执行 destroy-method 方法
private boolean enforceDestroyMethod = true;
// 是否是用户自定义的bean,创建AOP时为true
private boolean synthetic = false;
// 默认是用户定义的
private int role = BeanDefinition.ROLE_APPLICATION;
protected AbstractBeanDefinition() {
this(null, null);
}
...// 省略部分代码
@Override
public boolean isSingleton() {
return SCOPE_SINGLETON.equals(this.scope) || SCOPE_DEFAULT.equals(this.scope);
}
@Override
public boolean isPrototype() {
return SCOPE_PROTOTYPE.equals(this.scope);
}
...// 省略部分代码
}
AnnotatedBeanDefinition
该接口继承自BeanDefinition,添加了获取注解元数据信息的方法。
public interface AnnotatedBeanDefinition extends BeanDefinition {
AnnotationMetadata getMetadata();
@Nullable
MethodMetadata getFactoryMethodMetadata();
}
RootBeanDefinition
RootBeanDefinition是合并后的 BeanDefinition 对象。在Spring初始化Bean的之前,会将具有层次性关系的BeanDefinition进行合并,生成一个 RootBeanDefinition,用于后续实例化和初始化。
public class RootBeanDefinition extends AbstractBeanDefinition {
// BeanDefinitionHolder存储有Bean的名称、别名、BeanDefinition
@Nullable
private BeanDefinitionHolder decoratedDefinition;
// 是java反射包的接口,通过它可以查看Bean的注解信息
@Nullable
private AnnotatedElement qualifiedElement;
// 标识这个BeanDefinition是否是陈旧的,如果是true的话,在创建实例的时候会重新合并BeanDefinition
// 在markBeanAsCreated()会将该值变为true
// 至于为什么需要重新合并,是因为在bean工厂后置处理器中可能会对BeanDefinition进行修改,所以后续可能需要重新合并
volatile boolean stale;
// 是否允许缓存
boolean allowCaching = true;
// 工厂方法是否唯一
boolean isFactoryMethodUnique = false;
// 封装了java.lang.reflect.Type,提供了泛型相关的操作
@Nullable
volatile ResolvableType targetType;
// 缓存class,表明RootBeanDefinition存储哪个类的信息
@Nullable
volatile Class<?> resolvedTargetType;
// 是否是FactoryBean
@Nullable
volatile Boolean isFactoryBean;
// 工厂方法的返回类型
@Nullable
volatile ResolvableType factoryMethodReturnType;
// 工厂方法
@Nullable
volatile Method factoryMethodToIntrospect;
// 下面四个变量的锁
final Object constructorArgumentLock = new Object();
// 缓存已经解析的构造函数或是工厂方法,Executable是Method、Constructor类型的父类
@Nullable
Executable resolvedConstructorOrFactoryMethod;
// 构造函数参数是否解析完毕
boolean constructorArgumentsResolved = false;
// 已解析出来的构造函数参数
@Nullable
Object[] resolvedConstructorArguments;
// 待解析的构造函数参数
@Nullable
Object[] preparedConstructorArguments;
// 下面两个变量的锁
final Object postProcessingLock = new Object();
// 是否已通过MergedBeanDefinitionPostProcessor后置处理器处理
boolean postProcessed = false;
// 在生成代理的时候用来判断是否已经生成代理
@Nullable
volatile Boolean beforeInstantiationResolved;
// 实际缓存的类型是Constructor、Field、Method类型,它们都是Member的子类型
// 在checkConfigMembers()的时候会将需要注入的信息添加进来,保证需要注入的同一个字段或方法等只会注入一次
// 例如:如果在同一个字段上既有@Resource注解,又有@Autowired注解,由于@Resource注解先解析,所以会忽略@Autowired注解
@Nullable
private Set<Member> externallyManagedConfigMembers;
// 缓存的是通过注解已经执行过的初始化方法,防止同一个初始化方法执行多次
// 例如:一个类实现了InitializingBean接口,在afterPropertiesSet()方法上又添加了@PostConstruct注解,由于注解方式会
// 先执行,所以在后续执行InitializingBean接口初始化时,就不再执行这个已经执行过的方法了
@Nullable
private Set<String> externallyManagedInitMethods;
// 同理,这里是销毁方法,例如:DisposableBean的destroy()方法上又添加了@PreDestroy注解
@Nullable
private Set<String> externallyManagedDestroyMethods;
public RootBeanDefinition() {
super();
}
// ...省略部分代码
}
ChildBeanDefinition
该类可以让子 BeanDefinition 定义拥有从父 BeanDefinition 那里继承配置的能力(已经被GenericBeanDefinition所替代了)。
GenericBeanDefinition
通过xml配置的bean会解析为GenericBeanDefinition,其可以动态设置父 Bean,替代了原来的ChildBeanDefinition。比起ChildBeanDefinition更为灵活,ChildBeanDefinition在实例化的时候必须要指定一个parentName,而GenericBeanDefinition不需要。
public class GenericBeanDefinition extends AbstractBeanDefinition {
// 该bean父bean名称
@Nullable
private String parentName;
public GenericBeanDefinition() {
super();
}
public GenericBeanDefinition(BeanDefinition original) {
super(original);
}
@Override
public void setParentName(@Nullable String parentName) {
this.parentName = parentName;
}
@Override
@Nullable
public String getParentName() {
return this.parentName;
}
@Override
public AbstractBeanDefinition cloneBeanDefinition() {
return new GenericBeanDefinition(this);
}
// ...省略部分代码
}
AnnotatedGenericBeanDefinition
通过 @Import导入,@Configuration 注解标记配置类会被解析为AnnotatedGenericBeanDefinition,其父类是GenericBeanDefinition。
public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
// 注解元数据
private final AnnotationMetadata metadata;
// 工厂方法元数据
@Nullable
private MethodMetadata factoryMethodMetadata;
public AnnotatedGenericBeanDefinition(Class<?> beanClass) {
setBeanClass(beanClass);
this.metadata = AnnotationMetadata.introspect(beanClass);
}
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata, MethodMetadata factoryMethodMetadata) {
this(metadata);
Assert.notNull(factoryMethodMetadata, "MethodMetadata must not be null");
setFactoryMethodName(factoryMethodMetadata.getMethodName());
this.factoryMethodMetadata = factoryMethodMetadata;
}
// ...省略部分代码
}
ScannedGenericBeanDefinition
通过 @Service、@Controller、@Repository 以及 @Component 等注解标记的 Bean会被解析为ScannedGenericBeanDefinition,其父类是GenericBeanDefinition,并实现了AnnotatedBeanDefinition接口。
public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
// 注解源数据
private final AnnotationMetadata metadata;
public ScannedGenericBeanDefinition(MetadataReader metadataReader) {
Assert.notNull(metadataReader, "MetadataReader must not be null");
this.metadata = metadataReader.getAnnotationMetadata();
setBeanClassName(this.metadata.getClassName());
setResource(metadataReader.getResource());
}
// ...省略部分代码
}
ConfigurationClassBeanDefinition
通过 @Bean 注解标记的 Bean 会被解析为 ConfigurationClassBeanDefinition,其父类是RootBeanDefinition,并实现了AnnotatedBeanDefinition接口。
private static class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition {
// configClass元数据
private final AnnotationMetadata annotationMetadata;
// @Bean方法元数据
private final MethodMetadata factoryMethodMetadata;
// 标识该Bean是从哪个类创建出来的,也就是@Bean是从哪个类中定义的
private final String derivedBeanName;
public ConfigurationClassBeanDefinition(
ConfigurationClass configClass, MethodMetadata beanMethodMetadata, String derivedBeanName) {
this.annotationMetadata = configClass.getMetadata();
this.factoryMethodMetadata = beanMethodMetadata;
this.derivedBeanName = derivedBeanName;
setResource(configClass.getResource());
setLenientConstructorResolution(false);
}
// ...省略部分代码
}
ClassDerivedBeanDefinition
通过GenericApplicationContext.registerBean()方法注册的bean会被解析为ClassDerivedBeanDefinition,其父类是RootBeanDefinition。registerBean()方法可以在Spring启动之后通过class类向Spring容器中注册Bean(spring 5.0提供)。
private static class ClassDerivedBeanDefinition extends RootBeanDefinition {
public ClassDerivedBeanDefinition(Class<?> beanClass) {
super(beanClass);
}
public ClassDerivedBeanDefinition(ClassDerivedBeanDefinition original) {
super(original);
}
// 重写了获取class构造器的方法
@Override
@Nullable
public Constructor<?>[] getPreferredConstructors() {
Class<?> clazz = getBeanClass();
Constructor<?> primaryCtor = BeanUtils.findPrimaryConstructor(clazz);
if (primaryCtor != null) {
return new Constructor<?>[] {primaryCtor};
}
Constructor<?>[] publicCtors = clazz.getConstructors();
if (publicCtors.length > 0) {
return publicCtors;
}
return null;
}
@Override
public RootBeanDefinition cloneBeanDefinition() {
return new ClassDerivedBeanDefinition(this);
}
}
至此,BeanDefinition的知识点就讲完了。