springboot启动代码(自用)
1.springboot配置解释
@AutoConfigurationPackage //自动配置包
//@Import(AutoConfigurationPackages.Registrar.class)
@Import(AutoConfigurationImportSelector.class)//导入哪些组件的选择器
@SpringAutoConfiguration中的一些东西
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
AutoConfigurationEntry autoConfigurationEntry =getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
//这个方法在下面定义了 相对于1x的版本进行了代码的抽取和再封装
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
/**
* Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata}
* of the importing {@link Configuration @Configuration} class.
* @param autoConfigurationMetadata the auto-configuration metadata
* @param annotationMetadata the annotation metadata of the configuration class
* @return the auto-configurations that should be imported
*/
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
//获取候选的配置文件 Metadata=元数据
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
/**
* Return the auto-configuration class names that should be considered. By default
* this method will load candidates using {@link SpringFactoriesLoader} with
* {@link #getSpringFactoriesLoaderFactoryClass()}.
* @param metadata the source metadata
* @param attributes the {@link #getAttributes(AnnotationMetadata) annotation
* attributes}
* @return a list of candidate configurations
以下是getCandidateConfigurations方法
*/
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
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;
}
/**
* Load the fully qualified class names of factory implementations of the
* given type from {@value #FACTORIES_RESOURCE_LOCATION}, using the given
* class loader.
* @param factoryClass the interface or abstract class representing the factory
* @param classLoader the ClassLoader to use for loading resources; can be
* {@code null} to use the default
* @throws IllegalArgumentException if an error occurs while loading factory names
* @see #loadFactories
* 从这里获取enableautoConfiguration指定的值
*/
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
/**
* 此方法是loadSpringFactories(classLoader) 的内容 用来找类路径下的文件
**/
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = cache.get(classLoader);
if (result != null) {
return result;
}
try {
Enumeration<URL> urls = (classLoader != null ?
classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
//获取public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
result = new LinkedMultiValueMap<>();
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
for (Map.Entry<?, ?> entry : properties.entrySet()) {
String factoryClassName = ((String) entry.getKey()).trim();
for (String factoryName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
result.add(factoryClassName, factoryName.trim());
}
}
}
cache.put(classLoader, result);
return result;
}
catch (IOException ex) {
throw new IllegalArgumentException("Unable to load factories from location [" +
FACTORIES_RESOURCE_LOCATION + "]", ex);
}
}

springboot在启动的时候找到类路径下的META-INF/spring.factories文件从中获取EnableAutoConfiguration中指定的值,将这些值作为自动配置类导入到容器中,自动配置类生效,帮我们自动进行配置工作。

springboot 用的Google的gson
springboot启动代码(自用)的更多相关文章
- SpringBoot启动代码和自动装配源码分析
随着互联网的快速发展,各种组件层出不穷,需要框架集成的组件越来越多.每一种组件与Spring容器整合需要实现相关代码.SpringMVC框架配置由于太过于繁琐和依赖XML文件:为了方便快速集成第三 ...
- Springboot启动源码详解
我们开发任何一个Spring Boot项目,都会用到如下的启动类 @SpringBootApplication public class Application { public static voi ...
- SpringBoot启动流程解析
写在前面: 由于该系统是底层系统,以微服务形式对外暴露dubbo服务,所以本流程中SpringBoot不基于jetty或者tomcat等容器启动方式发布服务,而是以执行程序方式启动来发布(参考下图ke ...
- SpringBoot启动原理及相关流程
一.springboot启动原理及相关流程概览 springboot是基于spring的新型的轻量级框架,最厉害的地方当属自动配置.那我们就可以根据启动流程和相关原理来看看,如何实现传奇的自动配置 二 ...
- springboot启动的时候排除加载某些bean
由于公司把redis相关的配置类,工具类放在了一个类似common的工程里,这样以后肯定不可避免的出现某些项目可能并不需要使用redis,但是还是依赖common里的别的一些类库 所以排除spring ...
- SpringBoot启动tomcat源码解读
一.SpringBoot自动拉起Tomcat 原文链接:http://www.studyshare.cn/blog-front/blog/details/1136 SpringBoot框架是当前比较流 ...
- Springboot 启动详解
1.前言 最近一直在看Springboot和springcloud代码,看了将近20多天,对这两个系统的认知总算是入了门.后续应该会有一个系列的文章,本文就先从Springboot的启动入手. 2.容 ...
- SpringBoot 启动概述
透过现象看本质,SpringApplication 只是将一个典型的Spring应用的启动流程进行了扩展,因此,透彻理解 Spring 容器是打开 Spring Boot 大门的一把钥匙. Sprin ...
- SpringBoot启动加载类ApplicationRunner
SpringBoot启动加载类ApplicationRunner 有时希望项目在启动的时候加载一些系统参数,就要用到ApplicationRunner ApplicationRunner是一个接口,我 ...
随机推荐
- 制作Qt应用程序的插件(使用QtPlugin),对比DLL它是全平台通用的
在Qt下,插件有两种形式,一种是用于QtCreator下,扩展IDE功能.另一种是用于扩展开发者的应用.本文要讲的是后者. 定义一个纯虚类作为插件接口 #include <QtPlugin> ...
- 为什么使用剪切板时都用GlobalAlloc分配内存(历史遗留问题,其实没关系了)
我在使用剪切板时,发现通用的都是使用GlobalAlloc来分配内存,我就想不是说在Win32中GlobalAlloc和LocalAlloc是一样的那为什么不用LocalAlloc呢,原谅我的好奇心吧 ...
- 我们检测到您的浏览器不兼容传输层安全协议 (TLS) 1.1 或更高版本,此协议在 Internet 上用于确保您通信的安全性。
早上使用.Net WebClient类采集亚马逊数据,返回http 400 Bad Request错误,内容里面有“我们检测到您的浏览器不兼容传输层安全协议 (TLS) 1.1 或更高版本,此协议在 ...
- “多团队大规模”开发模式 - 基于SAP HANA平台的多团队产品研发
应用SAP HANA “官方”开发模式的伙伴们在转到“多团队大规模”开发模式时会遇到各式各样的心理不适应的状况,各种纠结.比如GIT Repository和HANA Repository冲突什么的. ...
- 前端自动化工具gulp入门基础
gulp是前端开发过程中经常要用到的工具,非常值得花时间去掌握.利用gulp,我们可以使产品流程脚本化,节约大量的时间,有条不紊地进行业务开发.本文简单讲一下入门gulp需要掌握的东西. 安装gulp ...
- 浅入深出Vue:数据渲染
今天来正式开始 vue的学习,首当其冲的当然是数据的渲染.毕竟数据就是拿来看的,看看如果使用 vue来展示数据. 为什么渲染 俗话说 "人靠衣装马靠鞍", 那咱们的代码就是得靠 U ...
- Junit4使用详解二:Junit4运行流程
1.新建一个测试用例,把下面的四个方法勾选以便查看效果 2.我们在各个方法里面写上输出语句 3.运行之后我们可以发现,它的执行顺序是这样的 注:junit4中的运行流程 1.@BeforeClass修 ...
- Kafka 学习之路(四)—— Kafka消费者详解
一.消费者和消费者群组 在Kafka中,消费者通常是消费者群组的一部分,多个消费者群组共同读取同一个主题时,彼此之间互不影响.Kafka之所以要引入消费者群组这个概念是因为Kafka消费者经常会做一些 ...
- spring 5.x 系列第20篇 ——spring简单邮件、附件邮件、内嵌资源邮件、模板邮件发送 (代码配置方式)
源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 邮件发送配置类为com.heibaiyin ...
- spring 5.x 系列第6篇 —— 整合 mybatis + druid 连接池 (代码配置方式)
源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 项目目录结构 1.创建maven工程,除了Spring基本依赖外,还需要导 ...