Spring boot源码分析一
2021/4/16 22:27:52
本文主要是介绍Spring boot源码分析一,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一、springBoot的start机制
Spring boot中的starter概念是非常重要的机制,能够抛弃以前繁杂的配置,统一集成进starter,应用者只需要引入starter jar包,spring boot就能自动扫描到要加载的信息。Spring Boot 通过starter对项目的依赖进行统一管理. starter利用了maven的传递依赖解析机制,把常用库聚合在一起, 组成了针对特定功能而定制的依赖starter。
starter机制是将经过测试不会起冲突的相关maven依赖聚合在一起形成新的pom文件。直接引入相关start就相当于引入了相关依赖。
比如我们引入spring-boot-starter-jdbc 依赖 该包下并没有任何其他的java文件只有pom 只包含了对应的jdbc相关的maven依赖。
springBoot自动配置原理
1、自动装配入口
@SpringBootApplication是一个组合注解其中的@EnableAutoConfiguration是实现自动装配的入口,该注解引入了一个AutoConfigurationImportSelector(在springBoot 1.3 之后开始使用EnableAutoConfigurationImportSelector实现自动装配,但是在springBoot1.5以后开始使用AutoConfigurationImportSelector来实现自动装配)
一、springBoot的start机制Spring boot中的starter概念是非常重要的机制,能够抛弃以前繁杂的配置,统一集成进starter,应用者只需要引入starter jar包,spring boot就能自动扫描到要加载的信息。Spring Boot 通过starter对项目的依赖进行统一管理. starter利用了maven的传递依赖解析机制,把常用库聚合在一起, 组成了针对特定功能而定制的依赖starter。
starter机制是将经过测试不会起冲突的相关maven依赖聚合在一起形成新的pom文件。直接引入相关start就相当于引入了相关依赖。 比如我们引入spring-boot-starter-jdbc 依赖 该包下并没有任何其他的java文件只有pom 只包含了对应的jdbc相关的maven依赖。
springBoot自动配置原理1、自动装配入口@SpringBootApplication是一个组合注解其中的@EnableAutoConfiguration是实现自动装配的入口,该注解引入了一个AutoConfigurationImportSelector(在springBoot 1.3 之后开始使用EnableAutoConfigurationImportSelector实现自动装配,但是在springBoot1.5以后开始使用AutoConfigurationImportSelector来实现自动装配) // 注解链 @SpringBootApplication => @EnableAutoConfiguration => @Import(AutoConfigurationImportSelector.class) 2、AutoConfigurationImportSelector自动装配类该类通过@Import注解在spring项目启动的时候引入进行实例化该配置类,实例化该类后会调用其内部类的AutoConfigurationGroup的process和selectImports进行自动装配,调用链如下: ConfigurationClassParser#parse(jBeanDefinitionHolder) =>DeferredImportSelectorHandler#process() =>DeferredImportSelectorGroupingHandler#processGroupImports() =>ConfigurationClassParser.DeferredImportSelectorGrouping#getImports() =>AutoConfigurationGroup的process() 和selectImports() ConfigurationClassParser入口以及有关@Import导入流程我们择机再写。
2.1、process()方法 /** * @param annotationMetadata @SpringBootApplication注解元数据 * @param deferredImportSelector 持有的一个自动装配对象 使用该类实现自动装配 */ public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) { //断言语句 Assert.state( deferredImportSelector instanceof AutoConfigurationImportSelector, () -> String.format("Only %s implementations are supported, got %s", AutoConfigurationImportSelector.class.getSimpleName(), deferredImportSelector.getClass().getName())); //获取springBoot应用红的所有的使用@Configuration修饰的配置类以及不需要排除的配置类 AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector) .getAutoConfigurationEntry(getAutoConfigurationMetadata(), annotationMetadata); //将获取到的全部配置类添加到两个集合中便于后续的使用 // autoConfigurationEntries(list自动配置类) // entries(map以配置类名和@SpringBootApplication注解元数据 key-value的形式存放) this.autoConfigurationEntries.add(autoConfigurationEntry); for (String importClassName : autoConfigurationEntry.getConfigurations()) { this.entries.putIfAbsent(importClassName, annotationMetadata); } } 上面的方法很好理解就是从项目中获取所有的配置类,从而在后面启动过程中将配置中的相关bean对象进行实例化。关键是配置类在哪里呢我们如何获取所有的配置类呢,这就要看getAutoConfigurationEntry()方法了。 SpringFactoriesLoader会加载classpath下所有JAR文件里面META-INF/spring.factories文件,这样在通过实例化配置类中的相关bean从而完成自动装配。 |
2、AutoConfigurationImportSelector自动装配类
该类通过@Import注解在spring项目启动的时候引入进行实例化该配置类,实例化该类后会调用其内部类的AutoConfigurationGroup的process和selectImports进行自动装配,调用链如下:
ConfigurationClassParser#parse(jBeanDefinitionHolder) =>DeferredImportSelectorHandler#process() =>DeferredImportSelectorGroupingHandler#processGroupImports() =>ConfigurationClassParser.DeferredImportSelectorGrouping#getImports() =>AutoConfigurationGroup的process() 和selectImports() |
ConfigurationClassParser入口以及有关@Import导入流程我们择机再写。
2.1、process()方法
/** * @param annotationMetadata @SpringBootApplication注解元数据 * @param deferredImportSelector 持有的一个自动装配对象 使用该类实现自动装配 */ public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) { //断言语句 Assert.state( deferredImportSelector instanceof AutoConfigurationImportSelector, () -> String.format("Only %s implementations are supported, got %s", AutoConfigurationImportSelector.class.getSimpleName(), deferredImportSelector.getClass().getName())); //获取springBoot应用红的所有的使用@Configuration修饰的配置类以及不需要排除的配置类 AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector) .getAutoConfigurationEntry(getAutoConfigurationMetadata(), annotationMetadata); //将获取到的全部配置类添加到两个集合中便于后续的使用 // autoConfigurationEntries(list自动配置类) // entries(map以配置类名和@SpringBootApplication注解元数据 key-value的形式存放) this.autoConfigurationEntries.add(autoConfigurationEntry); for (String importClassName : autoConfigurationEntry.getConfigurations()) { this.entries.putIfAbsent(importClassName, annotationMetadata); } } |
上面的方法很好理解就是从项目中获取所有的配置类,从而在后面启动过程中将配置中的相关bean对象进行实例化。关键是配置类在哪里呢我们如何获取所有的配置类呢,这就要看getAutoConfigurationEntry()方法了。
/** * * @param autoConfigurationMetadata 自动化配置类注解元数据信息 用于过滤不符合条件的配置类 * @param annotationMetadata #@SpringBootApplication注解 元数据信息 * @return */ protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry( AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } //获取@SpringBootApplication 的EnableAutoConfiguration自动装配相关的属性 // exclude和excludeName(显示设置的不需要进行自动化配置的配置类) AnnotationAttributes attributes = getAttributes(annotationMetadata); //SpringFactoriesLoader.loadFactoryNames获取项目中所有jar中META-INF/spring.factories下的所有配置类 List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); //去重 configurations = removeDuplicates(configurations); //获取不需要自动装配的配置类 依据注解中的exclude和excludeName Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); //过滤掉不符合条件的自动化配置类 configurations = filter(configurations, autoConfigurationMetadata); //向所有的AutoConfigurationImportListener发送AutoConfigurationImportListener事件通知 fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions); } |
SpringFactoriesLoader会加载classpath下所有JAR文件里面META-INF/spring.factories文件,这样在通过实例化配置类中的相关bean从而完成自动装配。
这篇关于Spring boot源码分析一的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)
- 2024-05-30【Java】百万数据excel导出功能如何实现
- 2024-05-30我们小公司,哪像华为一样,用得上IPD(集成产品开发)?
- 2024-05-30java excel上传--poi
- 2024-05-30安装笔记本应用商店的pycharm,再安排pandas等模块,说是没有打包工具?
- 2024-05-29java11新特性
- 2024-05-29哪些无用敏捷指标正在破坏敏捷转型?
- 2024-05-29鸿蒙原生应用再新丁!新华社 入局鸿蒙
- 2024-05-29设计模式 之 迭代器模式(Iterator)