Spring Boot-源码阅读-自动化Starter原理(四)
说明
使用方式参考Spring Boot-Starter(九)
原理:在Spring Boot-源码阅读-启动主流程(一) <14-18>处会将启动类封装成BeanDefinition 交给容器初始化。启动类都打了@SpringBootApplication注解
@SpringBootApplication public class FinancialAnalysisApplication { public static void main(String[] args) { SpringApplication.run(FinancialAnalysisApplication.class, args); } }
SpringBootApplication
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration //主要是这个注解触发自动化配置类加载 @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { }
EnableAutoConfiguration
@Import使用方式可参考https://www.cnblogs.com/LQBlog/p/15410425.html
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @AutoConfigurationPackage @Import(AutoConfigurationImportSelector.class)//通过Selector触发 public @interface EnableAutoConfiguration { }
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports
@Override public String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } //<1>加载需要注入容器的类全名称通过AutoConfigurationEntry封装 AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata); //转换成累的全名称 return org.springframework.util.StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); }
<1>
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry
protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } AnnotationAttributes attributes = getAttributes(annotationMetadata); //<2>获取自动化配置类的名字 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); configurations = removeDuplicates(configurations); Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = getConfigurationClassFilter().filter(configurations); fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions); }
<2>
org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#getAutoConfigurationEntry
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { //从Spring.factories获取对应的配置类 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."); return configurations; } protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
2020-02-28 设计模式之美学习-如何review代码发现代码质量问题(十四)
2020-02-28 springMVC源码阅读-通过画图理解一个请求生命周期(十二)
2019-02-28 elasticsearch-搜索之中英文搜索(四)