美文网首页
自动配置分析五

自动配置分析五

作者: 程序员札记 | 来源:发表于2023-05-13 22:53 被阅读0次

    refresh和自动配置大致流程

    image.png

    OnClassCondition的createOutcomesResolver创建结果解析器

    创建一个结果解析器对象,然后把起始索引和终止索引传进去,然后封装到ThreadedOutcomesResolver里。

        private OutcomesResolver createOutcomesResolver(String[] autoConfigurationClasses, int start, int end,
                AutoConfigurationMetadata autoConfigurationMetadata) {
            OutcomesResolver outcomesResolver = new StandardOutcomesResolver(autoConfigurationClasses, start, end,
                    autoConfigurationMetadata, getBeanClassLoader());
            try {
                return new ThreadedOutcomesResolver(outcomesResolver);
            }
            catch (AccessControlException ex) {
                return outcomesResolver;
            }
        }
    
    

    这个里面就会开个子线程,然后再线程里面进行结果解析。
    [图片上传失败...(image-822268-1684075686165)]

    StandardOutcomesResolver的resolveOutcomes解析结果

            @Override
            public ConditionOutcome[] resolveOutcomes() {
                return getOutcomes(this.autoConfigurationClasses, this.start, this.end, this.autoConfigurationMetadata);
            }
    
    

    就是遍历,然后获取对应条件的类名,这里就是我前面说的从META-INF/spring-autoconfigure-metadata.properties加载进来的,进行加载检查。

        private ConditionOutcome[] getOutcomes(String[] autoConfigurationClasses, int start, int end,
                    AutoConfigurationMetadata autoConfigurationMetadata) {
                ConditionOutcome[] outcomes = new ConditionOutcome[end - start];
                for (int i = start; i < end; i++) {
                    String autoConfigurationClass = autoConfigurationClasses[i];
                    if (autoConfigurationClass != null) {
                        String candidates = autoConfigurationMetadata.get(autoConfigurationClass, "ConditionalOnClass");
                        if (candidates != null) {
                            outcomes[i - start] = getOutcome(candidates);
                        }
                    }
                }
                return outcomes;
            }
    
    

    StandardOutcomesResolver的getOutcome

    如果有逗号的,说明有好几个,所以就循环尝试。

        private ConditionOutcome getOutcome(String candidates) {
                try {
                    if (!candidates.contains(",")) {
                        return getOutcome(candidates, this.beanClassLoader);
                    }
                    for (String candidate : StringUtils.commaDelimitedListToStringArray(candidates)) {
                        ConditionOutcome outcome = getOutcome(candidate, this.beanClassLoader);
                        if (outcome != null) {
                            return outcome;
                        }
                    }
                }
                catch (Exception ex) {
                    // We'll get another chance later
                }
                return null;
            }
    
    

    根据条件类型匹配,能匹配其实返回的是null,匹配不到才会相关信息对象。

            private ConditionOutcome getOutcome(String className, ClassLoader classLoader) {
                if (ClassNameFilter.MISSING.matches(className, classLoader)) {
                    return ConditionOutcome.noMatch(ConditionMessage.forCondition(ConditionalOnClass.class)
                            .didNotFind("required class").items(Style.QUOTE, className));
                }
                return null;
            }
    
    

    ClassNameFilter的MISSING判断是否没有

    是个枚举,判断要加载的类是否存在。

            MISSING {
    
                @Override
                public boolean matches(String className, ClassLoader classLoader) {
                    return !isPresent(className, classLoader);
                }
    
            };
    
    

    最终是这里:


    image.png

    如果不存在就会有这样的信息对象:


    image.png

    ThreadedOutcomesResolver的resolveOutcomes让线程join

    如果子线程没解析完,主线程解析完后,会调用到这里,还是会然子线程完成了,把结果返回才继续的。


    image.png

    解析后的结果

    是不是觉得很奇怪,前面索引少了几个,其实不是,只有没满足条件的才会放一个信息对象,满足条件的是null,所以没显示出来。

    image.png

    这个只是OnClassCondition一个条件过滤器,还有其他两个,原理一样的,只是内部判断可能比较复杂,这个自己研究研究吧。最终会生成一个是否匹配的数组,刚好true的地方就是前面null而没显示的地方:
    [图片上传失败...(image-cbf20b-1684075686165)]

    最终全部过滤后只剩下23个满足条件的:

    image.png

    其他的下次说吧。

    相关文章

      网友评论

          本文标题:自动配置分析五

          本文链接:https://www.haomeiwen.com/subject/gyvusdtx.html