spring的BeanDefinition体系
BeanDefinition是作为记录Bean的原始信息。读取完成配置文件后就要将配置文件解析为BeanDefinition。我们来分析一一下这个流程
bean的元数据
- BeanDefinition -> bean的元数据
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
//设置父定义的名称
void setParentName(@Nullable String parentName);
@Nullable
String getParentName();
//设置BeanClassName
void setBeanClassName(@Nullable String beanClassName);
@Nullable
String getBeanClassName();
//设置作用域
void setScope(@Nullable String scope);
@Nullable
String getScope();
//设置加载时间
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
//设置依赖
void setDependsOn(@Nullable String... dependsOn);
@Nullable
String[] getDependsOn();
//设置是否自动装配
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
//设置是否是自动装配的首选对象
void setPrimary(boolean primary);
boolean isPrimary();
//设置BeanFactory名称
void setFactoryBeanName(@Nullable String factoryBeanName);
@Nullable
String getFactoryBeanName();
//设置调用BeanFacory的指定方法
void setFactoryMethodName(@Nullable String factoryMethodName);
@Nullable
String getFactoryMethodName();
//返回bean构造方法的参数
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
//获取属性值
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
//设置初始化方法
void setInitMethodName(@Nullable String initMethodName);
@Nullable
String getInitMethodName();
//设置销毁方法
void setDestroyMethodName(@Nullable String destroyMethodName);
@Nullable
String getDestroyMethodName();
//设置bean的角色
void setRole(int role);
int getRole();
//设置bean的描述信息
void setDescription(@Nullable String description);
@Nullable
String getDescription();
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
//返回资源的描述信息
@Nullable
String getResourceDescription();
//获取原始的BeanDefinition信息
@Nullable
BeanDefinition getOriginatingBeanDefinition();
BeanDefinition继承两个接口AttributeAccessor、BeanMetadataElement
- 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();
}
AttributeAccessor定义了一系列有关属性的操作接口
- BeanMetadataElement
public interface BeanMetadataElement {
@Nullable
Object getSource();
}
BeanMetadataElement返回原始文件信息
- 子类
-
AbstractBeanDefinition抽象出文件定义的BeanDefintion
-
AnnotatedBeanDefinition基于注解的BeanDefinition
BeanDefinition的加载器
AnnotatedBeanDefinitionReader -> BeanDefinition的加载器
- BeanDefinitionReader.java
BeanDefinitionReader ,主要定义资源文件读取并转换为 BeanDefinition 的各个功能。 from 《Spring 源码深度解析》
现在普遍使用注解的方式来加载bean,因此用AnnotatedBeanDefinitionReader来分析加载资源的流程
- AnnotatedBeanDefinitionReader.java
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
注册代码主要分为两步
- 创建AnnotatedGenericBeanDefinition,set各种属性
- 注册BeanDefinition
其中注册registerBeanDefinition使用的是模板模式,根据不同的实现向注册BeanDefinition时进行不同的操作和检查
BeanDefinition的注册器
在上一步的结尾,通过调用BeanDefinitionReaderUtils.registerBeanDefinition实际上调用的是BeanDefinitionRegistry.registerBeanDefinition
注册BeanDefinition的过程其实就向beanDefinitionMap中添加元素的
总结
BeanDefinition作为bean定义的元数据,通过BeanDefinitionReader来进行加载。可以从文件、注解等地方加载定义。最后通过BeanDefinitionRegistry将BeanDefinitionReader加载进beanDefinitionMap中。