spring学习之源码分析--AnnotationConfigApplicationContext之register和scan

AnnotationConfigApplicationContext

AnnotationConfigApplicationContext继承了GenericApplicationContext,GenericApplicationContext里有个很重要的实例--DefaultListableBeanFactory。DefaultListableBeanFactory是spring中,默认注册、加载的实现。
sacn和register方法,是把扫描或者指定的配置bean信息,注册到容器中。

register

register方法是通过注解bean读取器AnnotatedBeanDefinitionReader来实现的。

public void register(Class... annotatedClasses) {
    Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
    this.reader.register(annotatedClasses);
}

register

AnnotatedBeanDefinitionReader的方法
按指定的配置bean注册信息

public void register(Class... annotatedClasses) {
    for (Class annotatedClass : annotatedClasses) {
        registerBean(annotatedClass);
    }
}

registerBean

public void registerBean(Class annotatedClass) {
    doRegisterBean(annotatedClass, null, null, null);
}

doRegisterBean

 void doRegisterBean(Class annotatedClass, @Nullable Supplier instanceSupplier, @Nullable String name,
        @Nullable Class[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
    // 其实就是创建BeanDefinition了,只是多了一个注解的属性metadata
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
    // @Conditional注解的判断在这里,如果不符合条件,就不注册了
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }
    // 回调用的
    abd.setInstanceSupplier(instanceSupplier);
    // 解析bean的作用域,scope,没有设置默认单例
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    // 解析bean的名称
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
    // 设置abd的Lazy, primary DependsOn, Role ,Description这五个属性
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
    // 特定限定符处理
    if (qualifiers != null) {
        for (Class 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,就是beanName和BeanDefinition的映射
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    // 是否有代理
    definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
    // 往容器注册BeanDefinition,同时注册别名
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

scan

scan方法是通过按类路径扫描注解bean的扫描器ClassPathBeanDefinitionScanner来实现的。

public void scan(String... basePackages) {
    Assert.notEmpty(basePackages, "At least one base package must be specified");
    this.scanner.scan(basePackages);
}

scan

ClassPathBeanDefinitionScanner的方法。
根据指定目录扫描,返回注册的bean的个数

public int scan(String... basePackages) {
    // 获取没扫描前bean的个数
    int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
    // 主要方法
    doScan(basePackages);

    // Register annotation config processors, if necessary.
    if (this.includeAnnotationConfig) {
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }
    // 当前bean的个数 - 没扫描前bean的个数 = 本次扫描时注册的bean的个数
    return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}

doScan

protected Set doScan(String... basePackages) {
    Assert.notEmpty(basePackages, "At least one base package must be specified");
    // 初始化容器
    Set beanDefinitions = new LinkedHashSet<>();
    for (String basePackage : basePackages) {
        // 根据路径扫描,获取BeanDefinition,这个BeanDefinition是ScannedGenericBeanDefinition。默认Component、ManagedBean、Named注解会被扫描进来,其中ManagedBean是JSR-250规范,Named是JSR-330规范,都需要额度的jar包支持。
        // register的conditionEvaluator判断@Conditional注解也是在这里判断。
        Set candidates = findCandidateComponents(basePackage);
        for (BeanDefinition candidate : candidates) {
            // 解析bean的作用域,scope,没有设置默认单例
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
            candidate.setScope(scopeMetadata.getScopeName());
            // 解析bean的名称
            String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
            // 设置默认的属性,比如lazy属性是false,还有autowireMode、dependencyCheck、initMethodName、destroyMethodName、enforceInitMethod、enforceDestroyMethod这几个属性设置
            if (candidate instanceof AbstractBeanDefinition) {
                postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
            }
            // 如果是注解的话,设置abd的Lazy, primary DependsOn, Role ,Description这五个属性
            if (candidate instanceof AnnotatedBeanDefinition) {
                AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
            }
            // 检查beanName如果没注册过,返回false。如果注册过了,要看是否兼容,如果不兼容,抛异常,如果兼容,这边不在注册。
            if (checkCandidate(beanName, candidate)) {
                // 定义一个BeanDefinitionHolder,就是beanName和BeanDefinition的映射
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                // 是否有代理
                definitionHolder =
                        AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                // 加入到beanDefinitions
                beanDefinitions.add(definitionHolder);
                // 往容器注册BeanDefinition,同时注册别名
                registerBeanDefinition(definitionHolder, this.registry);
            }
        }
    }
    return beanDefinitions;
}

你可能感兴趣的:(源码分析,spring,java)