Spring学习笔记整理(二)

入口代码

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);
    }

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章