AnnotatedBeanDefinitionReader 的register()方法向容器注册指定的注解Bean,注解Bean 定义读取器向容器注册注解Bean 的源码如下:
//注册多个注解Bean定义类
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
//注册一个注解Bean定义类
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null);
}
public <T> void registerBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier) {
doRegisterBean(annotatedClass, instanceSupplier, null, null);
}
public <T> void registerBean(Class<T> annotatedClass, String name, @Nullable Supplier<T> instanceSupplier) {
doRegisterBean(annotatedClass, instanceSupplier, name, null);
}
//Bean定义读取器注册注解Bean定义的入口方法
@SuppressWarnings("unchecked")
public void registerBean(Class<?> annotatedClass, Class<? extends Annotation>... qualifiers) {
doRegisterBean(annotatedClass, null, null, qualifiers);
}
//Bean定义读取器向容器注册注解Bean定义类
@SuppressWarnings("unchecked")
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
doRegisterBean(annotatedClass, null, name, qualifiers);
}
//Bean定义读取器向容器注册注解Bean定义类
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//根据指定的注解Bean定义类,创建Spring容器中对注解Bean的封装的数据结构
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(instanceSupplier);
//解析注解Bean定义的作用域,若@Scope("prototype"),则Bean为原型类型;
//若@Scope("singleton"),则Bean为单态类型
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//为注解Bean定义设置作用域
abd.setScope(scopeMetadata.getScopeName());
//为注解Bean定义生成Bean名称
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//处理注解Bean定义中的通用注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//如果在向容器注册注解Bean定义时,使用了额外的限定符注解,则解析限定符注解。
//主要是配置的关于autowiring自动依赖注入装配的限定条件,即@Qualifier注解
//Spring自动依赖注入装配默认是按类型装配,如果使用@Qualifier则按名称
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
//如果配置了@Primary注解,设置该Bean为autowiring自动依赖注入装//配时的首选
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
//如果配置了@Lazy注解,则设置该Bean为非延迟初始化,如果没有配置,
//则该Bean为预实例化
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
//如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一
//个autowiring自动依赖注入装配限定符,该Bean在进autowiring
//自动依赖注入装配时,根据名称装配限定符指定的Bean
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
//创建一个指定Bean名称的Bean定义对象,封装注解Bean定义类数据
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//根据注解Bean定义类中配置的作用域,创建相应的代理对象
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//向IOC容器注册注解Bean类定义对象
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
从上面的源码我们可以看出,注册注解Bean 定义类的基本步骤:
a、需要使用注解元数据解析器解析注解Bean 中关于作用域的配置。
b、使用AnnotationConfigUtils 的processCommonDefinitionAnnotations()方法处理注解Bean 定义类中通用的注解。
c、使用AnnotationConfigUtils 的applyScopedProxyMode()方法创建对于作用域的代理对象
d、通过BeanDefinitionReaderUtils 向容器注册Bean。