自动配置分析五

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

其他的下次说吧。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • ● 请你讲解一下数据连接池的工作机制? 考察点:连接池参考回答: J2EE 服务器启动时会建立一定数量的池连接,并...
    le_u阅读 376评论 0 0
  • Schema与数据类型优化 选择优化的数据类型 有几个简单的原则: 更小的通常更好一般情况下使用可以正确存储数据的...
    陈晨_软件五千言阅读 3,501评论 1 65
  • #================================================= ======...
    Gary_0102阅读 679评论 0 0
  • Mysql概述 数据库是一个易于访问和修改的信息集合。它允许使用事务来确保数据的安全性和一致性,并能快速处理百万条...
    彦帧阅读 13,638评论 10 461
  • 概要 64学时 3.5学分 章节安排 电子商务网站概况 HTML5+CSS3 JavaScript Node 电子...
    阿啊阿吖丁阅读 8,994评论 0 3