public AnnotationConfigApplicationContext(Class>... annotatedClasses) {
// 这里由于它有父类构造方法,故而先调用父类的构造方法,然后才会调用自己的构造方法
this();
register(annotatedClasses);
refresh();
}
在第一篇文章中,研究了this()中的源码,下面要来探究register(annotatedClasses);这行代码的秘密了。
一、注册配置类register(annotatedClasses);
这个标题,完全是翻译上面这行代码,下面就慢慢往下分析吧。先贴一下配置类AppConfig的代码,简单哦。
@Configuration
@ComponentScan("com.scorpios")
public class AppConfig {
}
AnnotationConfigApplicationContext类中的register()方法,发现这个方法可以传多个配置类。
public void register(Class>... annotatedClasses) {
// 这个reader读取器,就是在上面创建容器时无参构造器中创建的reader!
this.reader.register(annotatedClasses);
}
// 如果传入的是多个配置类,则要进行循环
public void register(Class>... annotatedClasses) {
for (Class> annotatedClass : annotatedClasses) {
// 把配置类转化为BeanDefinition放入到beanDefinitionMap中
registerBean(annotatedClass);
}
}
二、注册Bean
下面来研究下AnnotatedBeanDefinitionReader中的registerBean(annotatedClass);这个方法。
// 这个方法就是将一个类转化为一个BeanDefinition,给BeanDefinition里面的属性确定值三、小结void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name, @Nullable Class extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); // 判断这个类是否需要跳过解析,通过代码可以知道spring判断是否跳过解析,主要判断类有没有加特定注解 if (this.conditionevaluator.shouldSkip(abd.getmetadata())) { return; } // 不知道 abd.setInstanceSupplier(instanceSupplier); // 得到类的作用域 Scopemetadata scopemetadata = this.scopemetadataResolver.resolveScopemetadata(abd); // 把类的作用域添加到数据结构结构中 abd.setScope(scopemetadata.getScopeName()); // 通过beanNameGenerator生成类的名字, // 这地方是根据ClassName来截取的类名:com.scorpios.app.AppConfig String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); // 此处是处理类当中的通用注解,分析源码可以知道主要处理Lazy、Primary、DependsOn、Role、Description等注解 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); // 此参数是方法传入的,永远为空,如何给一个Bean传入Primary属性呢?两个方式,一个是加@Primary注解,一个就是往qualifiers中添加Primary if (qualifiers != null) { for (Class extends Annotation> qualifier : qualifiers) { // 如果配置了@Primary注解,如果加了则作为首选 if (Primary.class == qualifier) { abd.setPrimary(true); } else if (Lazy.class == qualifier) {// 懒加载 abd.setLazyInit(true); } else { // 如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一个根据名字自动装配的限定符 abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } // 忽略 for (BeanDefinitionCustomizer customizer : definitionCustomizers) { customizer.customize(abd); } // 这个BeanDefinitionHolder也是一个数据结构 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); // ScopedProxyMode 这个知识点比较复杂,需要结合web去理解 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopemetadata, definitionHolder, this.registry); BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
这个方法执行完,beanDefinitionMap中共有7个BeanDefinition对象,分别是之前创建读取器Reader时,Spring容器自己添加的6个,加上这个register(annotatedClasses);添加的一个。
见下图:
这里再强调一个概念,Spring容器需要将Class类转化成BeanDefinition,最后Spring容器是根据这个BeanDefinition来创建实例的。



