本文转载自【微信公众号:程序JAVA圈】经微信公众号授权转载,如需转载请与原文作者联系。
本文结论
源码使用spring boot2.6.6版本
开始自动配置的核心注解:@EnableAutoConfiguration
@EnableAutoConfiguration中使用了@Import(AutoConfigurationImportSelector.class)。
AutoConfigurationImportSelector实现了DeferredImportSelector这个接口,Spring容器在启动时,会在解析完其他所有程序员定义的配置类之后,来调用AutoConfigurationImportSelector中的selectImports方法,然后把该方法返回的类名对应的类作为配置类进行解析。
selectImports方法中通过spi的方式,找到所有的自动配置类
spring boot开启方式
一般使用@SpringBootApplication这个注解!
@SpringBootApplicationpublicclassMyApplication{publicstaticvoidmain(String[]args){SpringApplication.run(MyApplication.class);}}
@SpringBootApplication注解详细信息
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited// 下面这三个是最核心的!可以认为@SpringBootApplication是一个三合一注解。直接写这三个注解放在核心启动类上也是可以使用的!@SpringBootConfiguration// 标记当前是一个配置类@EnableAutoConfiguration// 开启自动配置// 扫描@ComponentScan(excludeFilters={@Filter(type=FilterType.CUSTOM,classes=TypeExcludeFilter.class),@Filter(type=FilterType.CUSTOM,classes=AutoConfigurationExcludeFilter.class)})public@interfaceSpringBootApplication{......}
开启自动配置的核心注解:@EnableAutoConfiguration
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited// 将主程序类所在包及所有子包下的组件到扫描到 spring 容器中。@AutoConfigurationPackage// 最核心的,自动配置的处理类!@Import(AutoConfigurationImportSelector.class)public@interfaceEnableAutoConfiguration{......}
@Import(AutoConfigurationImportSelector.class),Import了自动配置的核心处理类
自动配置处理类:AutoConfigurationImportSelector
AutoConfigurationImportSelector实现了DeferredImportSelector这个接口,Spring容器在启动时,会在解析完其他所有程序员定义的配置类之后,来调用AutoConfigurationImportSelector中的selectImports方法,然后把该方法返回的类名对应的类作为配置类进行解析。
AutoConfigurationImportSelector中的selectImports会利用SpringFactoriesLoader找到所有的META-INF/spring.factories文件中key为EnableAutoConfiguration.class的value值,也就是众多自动配置类的类名。
spring.factories配置类.png
// 实现了DeferredImportSelector这个接口!publicclassAutoConfigurationImportSelectorimplementsDeferredImportSelector,BeanClassLoaderAware,ResourceLoaderAware,BeanFactoryAware,EnvironmentAware,Ordered{......// 会在@Configuration都解析完成后执行(解析完程序员自定义的类之后执行)// annotationMetadata这个对象是我们main方法的信息@OverridepublicString[]selectImports(AnnotationMetadataannotationMetadata){// 判断是否开启自动配置:spring.boot.enableautoconfiguration配置的值为true(默认值为true)。没有开启的时候返回一个空数组。if(!isEnabled(annotationMetadata)){returnNO_IMPORTS;}// 获取自动配置类(spring.factories中导入的)AutoConfigurationEntryautoConfigurationEntry=getAutoConfigurationEntry(annotationMetadata);// 返回配置类的类名returnStringUtils.toStringArray(autoConfigurationEntry.getConfigurations());}....../*** 获取自动配置类(spring.factories中导入的)*/protectedAutoConfigurationEntrygetAutoConfigurationEntry(AnnotationMetadataannotationMetadata){// 判断是否开启自动配置:spring.boot.enableautoconfiguration配置的值为true(默认值为true)。没有开启的时候返回一个空对象。if(!isEnabled(annotationMetadata)){returnEMPTY_ENTRY;}// 获取@EnableAutoConfiguration的属性值(exclude,excludeName)。作用是获取需要排除的自动配置类。AnnotationAttributesattributes=getAttributes(annotationMetadata);// 获取spring.factories文件中所有的org.springframework.boot.autoconfigure.EnableAutoConfiguration的值List<String>configurations=getCandidateConfigurations(annotationMetadata,attributes);// 按照类名去重。每个jar包都可能有spring.factories中进行了配置,内容一致进行去重。// 去重代码为:return new ArrayList<>(new LinkedHashSet<>(list));configurations=removeDuplicates(configurations);// 获取需要排除的自动配置类。通过@EnableAutoConfiguration中的俩个属性(exclude,excludeName)进行指定。也可以通过属性spring.autoconfigure.exclude进行配置(逗号分隔)。Set<String>exclusions=getExclusions(annotationMetadata,attributes);// 排除操作checkExcludedClasses(configurations,exclusions);configurations.removeAll(exclusions);// 获取spring.factories中的AutoConfigurationImportFilter进行过滤// 拿到条件注解过滤:OnBeanCondition、OnClassCondition、OnWebApplicationCondition// 使用spring-autoconfigure-metadata.properties(编译的时候生成的文件!里面存一下条件注解对应关系)中的配置过滤。核心作用是加快启动速度!configurations=getConfigurationClassFilter().filter(configurations);// 发布一个事件,可以进行日志的打印(日志级别需要trans),展示出那些自动配置了,那些没有自动配置,因为什么导致无法进行自动配置...fireAutoConfigurationImportEvents(configurations,exclusions);// 最终的返回,全部是合格的自动配置类!returnnewAutoConfigurationEntry(configurations,exclusions);}/*** 获取spring.factories文件中所有的org.springframework.boot.autoconfigure.EnableAutoConfiguration的值*/protectedList<String>getCandidateConfigurations(AnnotationMetadatametadata,AnnotationAttributesattributes){// spi的方式找到spring.factories文件中所有的org.springframework.boot.autoconfigure.EnableAutoConfiguration的值// getSpringFactoriesLoaderFactoryClass()的逻辑是return EnableAutoConfiguration.class;List<String>configurations=SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader());// 无值得时候,抛出异常日志Assert.notEmpty(configurations,"No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");// 返回这些所有的自动配置类returnconfigurations;}}
声明:本文部分素材转载自互联网,如有侵权立即删除 。
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系管理员处理!
6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!
8. 精力有限,不少源码未能详细测试(解密),不能分辨部分源码是病毒还是误报,所以没有进行任何修改,大家使用前请进行甄别
丞旭猿论坛
暂无评论内容