2023-09-14  阅读(23)
原文作者:王伟王胖胖 原文地址: https://blog.csdn.net/wangwei19871103/article/details/105459893

refresh和自动配置大致流程

202309142258561461.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;
    		}
    	}

这个里面就会开个子线程,然后再线程里面进行结果解析。

202309142258579802.png

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

最终是这里:

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

202309142258593164.png

ThreadedOutcomesResolver的resolveOutcomes让线程join

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

202309142259001135.png

解析后的结果

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

202309142259010086.png
这个只是OnClassCondition一个条件过滤器,还有其他两个,原理一样的,只是内部判断可能比较复杂,这个自己研究研究吧。最终会生成一个是否匹配的数组,刚好true的地方就是前面null而没显示的地方:

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

202309142259031058.png
其他的下次说吧。
好了,今天就到这里了,希望对学习理解有帮助,大神看见勿喷,仅为自己的学习理解,能力有限,请多包涵。


Java 面试宝典是大明哥全力打造的 Java 精品面试题,它是一份靠谱、强大、详细、经典的 Java 后端面试宝典。它不仅仅只是一道道面试题,而是一套完整的 Java 知识体系,一套你 Java 知识点的扫盲贴。

它的内容包括:

  • 大厂真题:Java 面试宝典里面的题目都是最近几年的高频的大厂面试真题。
  • 原创内容:Java 面试宝典内容全部都是大明哥原创,内容全面且通俗易懂,回答部分可以直接作为面试回答内容。
  • 持续更新:一次购买,永久有效。大明哥会持续更新 3+ 年,累计更新 1000+,宝典会不断迭代更新,保证最新、最全面。
  • 覆盖全面:本宝典累计更新 1000+,从 Java 入门到 Java 架构的高频面试题,实现 360° 全覆盖。
  • 不止面试:内容包含面试题解析、内容详解、知识扩展,它不仅仅只是一份面试题,更是一套完整的 Java 知识体系。
  • 宝典详情:https://www.yuque.com/chenssy/sike-java/xvlo920axlp7sf4k
  • 宝典总览:https://www.yuque.com/chenssy/sike-java/yogsehzntzgp4ly1
  • 宝典进展:https://www.yuque.com/chenssy/sike-java/en9ned7loo47z5aw

目前 Java 面试宝典累计更新 400+ 道,总字数 42w+。大明哥还在持续更新中,下图是大明哥在 2024-12 月份的更新情况:

想了解详情的小伙伴,扫描下面二维码加大明哥微信【daming091】咨询

同时,大明哥也整理一套目前市面最常见的热点面试题。微信搜[大明哥聊 Java]或扫描下方二维码关注大明哥的原创公众号[大明哥聊 Java] ,回复【面试题】 即可免费领取。

阅读全文