1、注册方法概述
register(componentClasses) 注册配置类的信息。其中componentClasses 为传入的配置类class。
通过
AnnotatedBeanDefinitionReader的register(this.reader.register(componentClasses))方法。AnnotatedBeanDefinitionReader已经注册了系统自带的处理器以及方法。就可以直接解析配置类中的属性和方法了。最终调用的是org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean方法,遍历配置类以此处理。
主要处理的流程如下:
-
读取配置类的信息,将信息封装到
AnnotatedGenericBeanDefinition对象中。 -
通过注解工具处理
AnnotatedGenericBeanDefinition中的注解。 -
将配置类的
AnnotatedGenericBeanDefinition和beanName封装成BeanDefinitionHolder -
将
BeanDefinitionHolder注册到BeanDefinitionRegistry中,也就是当前的context(AnnotationConfigApplicationContext)中。
2、读取配置类的信息
主要方法:new AnnotatedGenericBeanDefinition(beanClass)
该方法主要获取配置类注解的元数据(
AnnotationMetadata),只是获取不做任何处理。该对象内部主要保存两个对象:
配置类的Class对象(
Object beanClass)配置类的注解元数据(
AnnotationMetadata metadata)
-
setBeanClass(beanClass)将当前的配置类交给AnnotatedGenericBeanDefinition对象 -
this.metadata = AnnotationMetadata.introspect(beanClass)通过AnnotationMetadata的静态方法获取配置类的注解元数据
3、设置配置类的其他属性
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
-
设置实例的创建方式(
abd.setInstanceSupplier(supplier))supplier参数默认为空,该参数可以将实例对象交给Spring管理,不需要遵守Bean严格的创建过程 -
设置实例的作用域(
abd.setScope(scopeMetadata.getScopeName()))也就是实例单例还是多例
4、通过注解工具处理AnnotatedGenericBeanDefinition 中的注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
解析注解元数据中的注定注解,并设置到Bean定义的属性中
处理的注解:
-
懒加载
@Lazy -
优先级
@Primary -
依赖条件
@DependsOn -
角色
@Role -
描述
@Description
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));
}
}
}
如果 qualifier 参数有值,则优先获取qualifier 中的属性并覆盖上面的值,包含的注解:
-
懒加载
@Lazy -
优先级
@Primary
5、封装BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
将BeanName和Bean的定义信息封装成新的对象。如果是代理对象则按照代理对象封装
BeanDefinitionHolder。
6、Bean定义信息注册到当前的Context
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
注册信息主要是三个属性
beanDefinition、beanName、aliases。将这些属性注册到当前的Context(registry)中

7、小结
注册配置的方法很简单,就是解析配置的注解信息,并装所有的注解信息、Bean的名称、别名注册到
AnnotationConfigApplicationContext(registry)中。



















