SpringBoot 刷新上下文5--处理其他注解

SpringBoot刷新上下文一共七篇,基于SpringBoot 2.2.7.RELEASE,Spring 5.2.6.RELEASE
SpringBoot 刷新上下文1–主流程
SpringBoot 刷新上下文2–执行BeanDefinitionRegistryPostProcessor
SpringBoot 刷新上下文3–解析引导类
SpringBoot 刷新上下文4–处理ComponentScan
SpringBoot 刷新上下文5–处理其他注解
SpringBoot 刷新上下文6–加载并注册BeanDefinition
SpringBoot 刷新上下文7–执行BeanFactoryPostProcessor

2.1.3.1.2、处理其他注解
2.1.3.1.2.1、处理配置类内部的类
//org.springframework.context.annotation.ConfigurationClassParser#processMemberClasses
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter) throws IOException {
	//获取引导类的内部类,这里会递归处理
    Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
    if (!memberClasses.isEmpty()) {
        List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
        //获取内部类是配置类的类
        for (SourceClass memberClass : memberClasses) {
            if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
                !memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
                candidates.add(memberClass);
            }
        }
        //排序
        OrderComparator.sort(candidates);
        //遍历
        for (SourceClass candidate : candidates) {
            // 处理 error warn的类
            if (this.importStack.contains(configClass)) {
                this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
            }
            else {
                this.importStack.push(configClass);
                try {
                    //处理内部类是配置类的类	递归了
                    processConfigurationClass(candidate.asConfigClass(configClass), filter);
                }
                finally {
                    this.importStack.pop();
                }
            }
        }
    }
}
2.1.3.1.2.2、处理@PropertySource
//org.springframework.context.annotation.ConfigurationClassParser#processPropertySource
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
    // 获取资源name
    String name = propertySource.getString("name");
    if (!StringUtils.hasLength(name)) {
        name = null;
    }
    // 获取 encoding
    String encoding = propertySource.getString("encoding");
    if (!StringUtils.hasLength(encoding)) {
        encoding = null;
    }
    // 获取 配置的值,资源的位置
    String[] locations = propertySource.getStringArray("value");
    Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
    boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");

    Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
    PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
                                     DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));
	//遍历所有 配置的资源路径
    for (String location : locations) {
        try {
            //解析占位符,获取真实路径
            String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
            //读取资源
            Resource resource = this.resourceLoader.getResource(resolvedLocation);
            //创建PropertySource并添加到Environment的propertiSources
            addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
        }
        catch (IllegalArgumentException | FileNotFoundException | UnknownHostException ex) {
            ...
        }
    }
}
2.1.3.1.2.3、处理@Import

这里默认会得到引导类 @SpringBootApplication 注解中 @EnableAutoConfigration 注解中配置的类,这个注解前面讲过,不再陈述解析过程。

//org.springframework.context.annotation.ConfigurationClassParserprocessImports
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) {

    if (importCandidates.isEmpty()) {
        return;
    }

    if (checkForCircularImports && isChainedImportOnStack(configClass)) {
        this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
    }
    else {
        this.importStack.push(configClass);
        try {
            //遍历扫描到的 @Import 导入的类
            for (SourceClass candidate : importCandidates) {
                //导入类是否派生自 ImportSelector
                if (candidate.isAssignable(ImportSelector.class)) {
                    // Candidate class is an ImportSelector -> delegate to it to determine imports
                    //获取候选类的 class
                    Class<?> candidateClass = candidate.loadClass();
                    //加载候选类
                    ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
                                                                                   this.environment, this.resourceLoader, this.registry);
                    Predicate<String> selectorFilter = selector.getExclusionFilter();
                    if (selectorFilter != null) {
                        exclusionFilter = exclusionFilter.or(selectorFilter);
                    }
                    //@EnableAutoConfigration 注解上配置类在这里处理,导入自动装配
                    // AutoConfigurationImportSelector
                    if (selector instanceof DeferredImportSelector) {
                        //将实现DeferredImportSelector的类加入
                        this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
                    }
                    else {
                        //执行候选类的 selectImports 方法获取要导入的类
                        String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
                        Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
                        //递归处理
                        processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
                    }
                }
                //是否派生自 ImportBeanDefinitionRegistrar
                //class org.springframework.boot.autoconfigure.AutoConfigurationPackages$Registrar
                //@EnableAutoConfiguration 注解上标的类,获取扫描包
                else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
                    // Candidate class is an ImportBeanDefinitionRegistrar ->
                    // delegate to it to register additional bean definitions
                    Class<?> candidateClass = candidate.loadClass();
                    ImportBeanDefinitionRegistrar registrar =
                        ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
                                                             this.environment, this.resourceLoader, this.registry);
                    configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
                }
                else {
                    // Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
                    // process it as an @Configuration class
                    // 导入类不是ImportSelector 或 ImportBeanDefinitionRegistrar,
                    // 按配置类处理
                    this.importStack.registerImport(
                        currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
                    //导入的其他类,递归处理
                    processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
                }
            }
        }
        catch (BeanDefinitionStoreException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanDefinitionStoreException(
                "Failed to process import candidates for configuration class [" +
                configClass.getMetadata().getClassName() + "]", ex);
        }
        finally {
            this.importStack.pop();
        }
    }
}

将实现DeferredImportSelector的类加入集合

private List<DeferredImportSelectorHolder> deferredImportSelectors = new ArrayList<>();
//org.springframework.context.annotation.ConfigurationClassParser.DeferredImportSelectorHandler#handle
public void handle(ConfigurationClass configClass, DeferredImportSelector importSelector) {
    DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(configClass, importSelector);
    if (this.deferredImportSelectors == null) {
        DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
        handler.register(holder);
        handler.processGroupImports();
    }
    else {
        //加入
        this.deferredImportSelectors.add(holder);
    }
}
2.1.3.1.2.4、处理@Bean
private final MetadataReaderFactory metadataReaderFactory;
//org.springframework.context.annotation.ConfigurationClassParser#retrieveBeanMethodMetadata
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
    //获取类注解
    AnnotationMetadata original = sourceClass.getMetadata();
    //获取@Bean 标注的所有方法
    Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
    if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
        // Try reading the class file via ASM for deterministic declaration order...
        // Unfortunately, the JVM's standard reflection returns methods in arbitrary
        // order, even between different runs of the same application on the same JVM.
        try {
            AnnotationMetadata asm =
                this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
            Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
            if (asmMethods.size() >= beanMethods.size()) {
                Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
                for (MethodMetadata asmMethod : asmMethods) {
                    for (MethodMetadata beanMethod : beanMethods) {
                        if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
                            selectedMethods.add(beanMethod);
                            break;
                        }
                    }
                }
                if (selectedMethods.size() == beanMethods.size()) {
                    // All reflection-detected methods found in ASM method set -> proceed
                    beanMethods = selectedMethods;
                }
            }
        }
        catch (IOException ex) {
            logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
            // No worries, let's continue with the reflection metadata we started with...
        }
    }
    return beanMethods;
}
2.1.3.1.2.5、处理接口的默认方法
//org.springframework.context.annotation.ConfigurationClassParser#processInterfaces
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
    for (SourceClass ifc : sourceClass.getInterfaces()) {
        //调用上面的方法,获取接口默认方法作为@Bean标注方法的方法
        Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc);
        for (MethodMetadata methodMetadata : beanMethods) {
            if (!methodMetadata.isAbstract()) {
                // A default method or other concrete method on a Java 8+ interface...
                configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
            }
        }
        //递归
        processInterfaces(configClass, ifc);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值