spring的BeanDefinition体系


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继承两个接口AttributeAccessorBeanMetadataElement

  • 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返回原始文件信息

  • 子类

8D1wJx.png

  • 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);
	}

注册代码主要分为两步

  1. 创建AnnotatedGenericBeanDefinition,set各种属性
  2. 注册BeanDefinition
    其中注册registerBeanDefinition使用的是模板模式,根据不同的实现向注册BeanDefinition时进行不同的操作和检查

BeanDefinition的注册器

在上一步的结尾,通过调用BeanDefinitionReaderUtils.registerBeanDefinition实际上调用的是BeanDefinitionRegistry.registerBeanDefinition

注册BeanDefinition的过程其实就向beanDefinitionMap中添加元素的

总结

BeanDefinition作为bean定义的元数据,通过BeanDefinitionReader来进行加载。可以从文件、注解等地方加载定义。最后通过BeanDefinitionRegistryBeanDefinitionReader加载进beanDefinitionMap中。


  TOC