入口代码:
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
执行了AnnotationConfigApplicationContext中的一个构造函数
找到第一行代码 看AnnotationConfigApplicationContext的空参构造
创建一个AnnotatedBeanDefinitionReader
创建一个ClassPathBeanDefinitionScanner
AnnotatedBeanDefinitionReader是什么?
这个类的主要作用就是注册BeanDefinition,与之相类似的功能的类还有一个就是ClassPathBeanDefinitionScanner。它们最大的不同在于AnnotatedBeanDefinitionReader支持注册单个的BeanDefinition,而ClassPathBeanDefinitionScanner会一次注册所有扫描到的BeanDefinition。
AnnotatedBeanDefinitionReader源码解析
// 这里只保留了这个类中的部分代码,其余不重要我都没有放出来
public class AnnotatedBeanDefinitionReader {
// 上面我们已经说了,这个reader对象主要的工作就是注册BeanDefinition,那么将BeanDefinition注册到哪里去呢?所以它内部就保存了一个BeanDefinition的注册表。对应的就是我们代码中的AnnotationConfigApplicationContext
private final BeanDefinitionRegistry registry;
// 见名知意,Bean名称的生成器,生成BeanName
private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();
// 解析@Scope注解
private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
// 解析@Conditional注解
private ConditionEvaluator conditionEvaluator;
// 将解析指定的类成为BeanDefinition并注册到容器中
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
doRegisterBean(annotatedClass, null, name, qualifiers);
}
// 真正的执行注册的方法
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
// Spring在这里写死了,直接new了一个AnnotatedGenericBeanDefinition,也就是说通过reader对象注册的BeanDefinition都是AnnotatedGenericBeanDefinition。
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
// 调用conditionEvaluator的shouldSkip方法
// 判断当前的这个bd是否需要被注册
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
// 在注册时可以提供一个instanceSupplier
abd.setInstanceSupplier(instanceSupplier);
// 解析@Scope注解,得到一个ScopeMetadata
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
// 将@Scope注解中的信息保存到bd中
abd.setScope(scopeMetadata.getScopeName());
// 调用beanNameGenerator生成beanName
// 所谓的注册bd就是指定将bd放入到容器中的一个beanDefinitionMap中
// 其中的key就是beanName,value就是解析class后得到的bd
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 这句代码将进一步解析class上的注解信息,Spring在创建这个abd的信息时候就已经将当前的class放入其中了,所有这行代码主要做的就是通过class对象获取到上面的注解(包括@Lazy,@Primary,@DependsOn注解等等),然后将得到注解中对应的配置信息并放入到bd中的属性中
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
// 下面的这段不用过多关注,为了文章的完整性我这里还是说说我的理解
// 正常的容器启动阶段qualifiers肯定等于null
// 我能想到的不为空的方法就是直接在外部调用了register方法并且出入了qualifiers参数
// 就是说我们手动直接注册了一个类,但是我们没有在类上添加@Lazy,@Primary注解,但是我们又希望能将其标记为Primary为true/LazyInit为true,这个时候就手动传入Primary.class跟Lazy.class即可。
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));
}
}
}
// 我们注册时,我们可以传入一些回调方法,在解析得到bd后调用
for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
customizer.customize(abd);
}
// bd中是没有beanName属性的,BeanDefinitionHolder中就是保存了beanName以及对应的BeanDefinition
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// 这个地方主要是解析Scope中的ProxyMode属性,默认为no,不生成代理对象
// 后文做详细分析
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 注册bd到容器中,实际上最终就是将bd放到了beanFactory中的一个map里(beanDefinitionMap)
// key为beanName,value为bd
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
}