前言:
还是顺着spring容器初始化的流程来进行跟踪,在上一节解析完两个扫描器的初始化后,本节将继续解析注解扫描器的注册。
此处代码跟踪的注册一般是注册配置类,不过此方法不止一处调用,故作通用解析
1.解析AnnotationConfigApplicationContext构造方法的第五行
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//有父类,先调用父类的构造方法,然后调用自己的构造方法
//在自己的构造方法里初始化一个读取器和一个扫描器
this();
register(annotatedClasses);
//初始化spring的环境
refresh();
}
接下来看register方法
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
//把一个class转为BeanDefinition放入到BeanDefinitionMap中
//此处使用上一节初始化的AnnotatedBeanDefinitionReader的实例中的register方法进行注册
this.reader.register(annotatedClasses);
}
接下来我们看AnnotatedBeanDefinitionReader#register的详细
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//将传入的类转为BeanDefinition类型
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
//判断此类是否有@Conditional注解,而且是否满足Condition接口实现类的matches条件,满足的话,就继续往后走,不满足则跳过不再注册
//@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
//获取并添加@Scope注解
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//处理类上的通用注解:Lazy DependsOn Primary Role
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//此处正常流程访问不到,可能spring内部有使用会传入注解数组qualifiers,正常初始化spring容器qualifiers为空
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也是一个数据结构,里面放一个BeanDefinition,beanName
//此处的封装我理解是beanName可以使用别名,24行有详细获取方式
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//将BeanDefinition放入beanDefinitionMap
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
将BeanDefinition放入beanDefinitionMap后即注册完成了!
2.AnnotatedBeanDefinitionReader的注册流程的步骤
1.将类对象Class封装为BeanDefinition对象
2.@Conditional注解解析,要是不符合@Conditional的match条件,则不进行注册
3.给BeanDefinition对象设置Scope Lazy DependsOn Primary Role等注解的值
4.将BeanDefinition封装为BeanDefinitionHolder对象,此处课理解为对BeanDefinition的扩展,主要是扩展一个beanName别名
5.将BeanDefinition对象放入spring容器BeanFactory里的BeanDefinitionMap里