}
//加载自动配置的元信息
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//获取候选配置类
List configurations = getCandidateConfigurations(annotationMetadata,
attributes);
//去掉重复的配置类
configurations = removeDuplicates(configurations);
//获得注解中被exclude和excludeName排除的类的集合
Set exclusions = getExclusions(annotationMetadata, attributes);
//检查被排除类是否可实例化、是否被自动注册配置所使用,不符合条件则抛出异常
checkExcludedClasses(configurations, exclusions);
//从候选配置类中去除掉被排除的类
configurations.removeAll(exclusions);
//过滤
configurations = filter(configurations, autoConfigurationMetadata);
//将配置类和排除类通过事件传入到监听器中
fireAutoConfigurationImportEvents(configurations, exclusions);
//最终返回符合条件的自动配置类的全限定名数组
return StringUtils.toStringArray(configurations);
}
这里需要关注的的是如何得到候选的配置类,可以看到所有的配置信息通过**getCandidateConfigurations()**得到,并最终由一个列表保存。我们继续查看getCandidateConfigurations()方法。
继续进入loadFactoryNames()方法,可以发现一个获取资源的可疑地址:FACTORIES_RESOURCE_LOCATION
再进入FACTORIES_RESOURCE_LOCATION,发现值为:META-INF/spring.factories
public static final String FACTORIES_RESOURCE_LOCATION = “META-INF/spring.factories”;
简述以上过程就是:getCandidateConfigurations()方法通过SpringFactoriesLoader加载器加载META-INF/spring.factories文件,首先通过这个文件获取到每个配置类的url,再通过这些url将它们封装成Properties对象,最后解析内容存于Map<String,List>中。
下面是spring.factories文件的内容格式,根据它我们可以清晰地了解Map<String,List>中都存了些什么。其中Key值为:org.springframework.boot.autoconfigure.EnableAutoConfiguration,Value值为后面的各种XXXAutoConfiguration类。
最后通过loadFactoryNames传递过来的class名称作为Key从Map中获得该类的配置列表,而这个class名称是什么呢?回到之前的SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader())方法,注意第一个参数,是一个方法,我们进入这个方法,发现返回的是EnableAutoConfiguration.class,这即是我们需要的class名称。
/**
-
Return the class used by {@link SpringFactoriesLoader} to load configuration
-
candidates.
-
@return the factory class
*/
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
最终,getCandidateConfigurations()方法获取到了候选配置类并存于List中。之所以说是“候选”,是因为它们后续还需要经过一系列的去重、排除、过滤等操作,最终会通过selectImports()方法返回一个自动配置类的全限定名数组。
六、@Condition
在上面的步骤中我们得到了一个动配置类的全限定名数组,这些配置类需要在满足@Condition后才能真正的被注册到Spring容器之中。但在Spring Boot项目中我们更多的是看到@Condition注解的衍生注解,如下:
@ConditionOnBean | 在容器中有指定Bean的条件下。 |
@ConditionalOnMissingBean | 在容器中没有指定Bean的条件下。 |
@ConditionOnClass | 在classpath类路径下有指定类的条件下。 |
@ConditionalOnMissingClass | 在classpath类路径下没有指定类的条件下。 |
@ConditionalOnResource | 类路径是否有指定的值。 |
@ConditionalOnWebApplication | 在项目是一个Web项目的条件下。 |
@ConditionOnProperty | 在指定的属性有指定的值条件下。 |
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
总结
总体来说,如果你想转行从事程序员的工作,Java开发一定可以作为你的第一选择。但是不管你选择什么编程语言,提升自己的硬件实力才是拿高薪的唯一手段。
如果你以这份学习路线来学习,你会有一个比较系统化的知识网络,也不至于把知识学习得很零散。我个人是完全不建议刚开始就看《Java编程思想》、《Java核心技术》这些书籍,看完你肯定会放弃学习。建议可以看一些视频来学习,当自己能上手再买这些书看又是非常有收获的事了。
,你会有一个比较系统化的知识网络,也不至于把知识学习得很零散。我个人是完全不建议刚开始就看《Java编程思想》、《Java核心技术》这些书籍,看完你肯定会放弃学习。建议可以看一些视频来学习,当自己能上手再买这些书看又是非常有收获的事了。
[外链图片转存中…(img-D9CW9A7j-1711154010224)]