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)
中。