SpringBoot运行原理初探

运行原理初探

其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件!

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.2.5.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent>

点进去,发现还有一个父依赖

    <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>2.2.5.RELEASE</version><relativePath>../../spring-boot-dependencies</relativePath></parent>

这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心;

以后我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了;

启动器 spring-boot-starter

 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency>

springboot-boot-starter-xxx:就是spring-boot的场景启动器

spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件;

SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义 starter;

主启动类

分析完了 pom.xml 来看看这个启动类

//@SpringBootApplication 来标注一个主程序类//说明这是一个Spring Boot应用
@SpringBootApplication
public class SpringbootApplication {public static void main(String[] args) {     //以为是启动了一个方法,没想到启动了一个服务      SpringApplication.run(SpringbootApplication.class, args);   }
}

但是**一个简单的启动类并不简单!**我们来分析一下这些注解都干了什么

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YQvAiVOn-1609943971034)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210106214306610.png)]

@SpringBootApplication

作用:标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

进入这个注解:可以看到上面还有很多其他注解!

@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan(    excludeFilters = {@Filter(    type = FilterType.CUSTOM,    classes = {TypeExcludeFilter.class}), @Filter(    type = FilterType.CUSTOM,    classes = {AutoConfigurationExcludeFilter.class})})public @interface SpringBootApplication {    // ......}

@ComponentScan

这个注解在Spring中很重要 ,它对应XML配置中的元素。

作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

@SpringBootConfiguration

作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;

我们继续进去这个注解查看

// 点进去得到下面的 
@Component
@Configuration//spring配置类
public @interface SpringBootConfiguration {}
@Component//说明也是一个spring组件
public @interface Configuration {}

这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;

里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!

我们回到 SpringBootApplication 注解中继续看。

@EnableAutoConfiguration

@EnableAutoConfiguration :开启自动配置功能

以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;

@EnableAutoConfiguration告诉SpringBoot开启自动配置功能,这样自动配置才能生效;

点进注解接续查看:

@AutoConfigurationPackage :自动配置包

@Import({Registrar.class})public @interface AutoConfigurationPackage {}

@import :Spring底层注解@import , 给容器中导入一个组件

Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;

这个分析完了,退到上一步,继续看

@Import({AutoConfigurationImportSelector.class}) :给容器导入组件 ;

AutoConfigurationImportSelector :自动配置导入选择器,那么它会导入哪些组件的选择器呢?我们点击去这个类看源码:

1、这个类中有一个这样的方法

// 获得候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { //这里的getSpringFactoriesLoaderFactoryClass()方法    返回的就是我们最开始看的启动自动导入配置文件的注解类; EnableAutoConfiguration   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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;}

META-INF/spring.factories//自动配置的核心文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Wzsr8vGN-1609943971036)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210106215520041.png)]

2、这个方法又调用了 SpringFactoriesLoader 类的静态方法!我们进入SpringFactoriesLoader类loadFactoryNames() 方法

public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {    String factoryClassName = factoryClass.getName();                        //这里它又调用了 loadSpringFac tories 方法                                                     return loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());}

3、我们继续点击查看 loadSpringFactories 方法

  private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {    //获得classLoader , 我们返回可以看到这里得到的就是EnableAutoConfiguration标注的类本身   MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);    if (result != null) {        return result;    } else {        try {            //去获取一个资源 "META-INF/spring.factories"          Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");            LinkedMultiValueMap result = new LinkedMultiValueMap();//将读取到的资源遍历,封装成为一个Properties            while(urls.hasMoreElements()) {                URL url = (URL)urls.nextElement();                UrlResource resource = new UrlResource(url);                Properties properties = PropertiesLoaderUtils.loadProperties(resource);                Iterator var6 = properties.entrySet().iterator();while (var6.hasNext()) {Entry<?, ?> entry = (Entry) var6.next();String factoryClassName = ((String) entry.getKey()).trim();String[] var9 = StringUtils.commaDelimitedListToStringArray((String) entry.getValue());int var10 = var9.length;for (int var11 = 0; var11 < var10; ++var11) {String factoryName = var9[var11];result.add(factoryClassName, factoryName.trim());}}}cache.put(classLoader,result);            return result;
} catch(IOException var13){throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]",var13);}}}

4、发现一个多次出现的文件:spring.factories,全局搜索它

我们根据源头打开spring.factories , 看到了很多自动配置的文件;这就是自动配置根源所在![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fBpFxnwS-1609943971038)(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==)]

WebMvcAutoConfiguration

我们在上面的自动配置类随便找一个打开看看,比如 :WebMvcAutoConfiguration

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eXIoKdKv-1609943971041)(C:\Users\王东梁\AppData\Roaming\Typora\typora-user-images\image-20210106222618060.png)]

可以看到这些一个个的都是JavaConfig配置类,而且都注入了一些Bean,可以找一些自己认识的类,看着熟悉一下!

所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。

结论:

  1. SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
  2. 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
  3. 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;
  4. 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
  5. 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/327655.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一款全新的基于IntelliJ和ReSharper的跨平台.NET IDE

JetBrains Rider在今年一月份露面&#xff0c;后来的大部分时间被用在了内部早期预览版上&#xff0c;还没有为公开发布做好准备。而现在&#xff0c;我们可以下载早期预览版&#xff0c;并感受在IntelliJ平台上开发.NET是一种什么体验。早期预览版还存在一些问题&#xff0c;不…

mysql自动插入的时间不对 差8小时

MySQL插入时间差八小时问题的解决方法 更新时间&#xff1a;2019年12月15日 10:19:12 转载 作者&#xff1a;lankeren 这篇文章主要给大家介绍了关于MySQL插入时间差八小时问题的解决方法&#xff0c;文中通过示例代码介绍的非常详细&#xff0c;对大家学习或者使用MySQL具…

Ajax基本案例详解之$.post的实现

Ajax的post实现&#xff1a; 看这篇之前建议大家去看看前面两篇文章&#xff1a; 1.Ajax基本案例详解之$.ajax的实现 2.Ajax基本案例详解之$.get的实现 现在写一下$.post()里面的主要内容&#xff1a; $.post("doindex.jsp","email"$("#emai…

windows为什么把linux打败了,快二十年了,人们为什么还是没有抛弃 Windows 转向 Linux?...

原标题&#xff1a;快二十年了&#xff0c;人们为什么还是没有抛弃 Windows 转向 Linux&#xff1f;自伟大的 Linux 操作系统诞生以来&#xff0c; 许多网友都试图列举出 Linux 可能是更好选择的具体原因 &#xff0c;其中包括&#xff1a;Linux 上的更新速度很快&#xff0c;“…

Java IO 概述

转载自 Java IO 概述 译文链接 作者: Jakob Jenkov 译者: 李璟(jlee381344197gmail.com) 校对&#xff1a;方腾飞 在这一小节&#xff0c;我会试着给出Java IO(java.io)包下所有类的概述。更具体地说&#xff0c;我会根据类的用途对类进行分组。这个分组将会使你在未来的工…

ASP.NET Core WebListener 服务器

WebListener是一个只能运行在Windows上的ASP.NET Core web服务器&#xff0c;基于Http.Sys内核模块驱动构建。在不借助IIS作为反向代理服务器的情况下&#xff0c;WebListener可以替代Kestrel用来与直接与互联网相连。实际上&#xff0c;WebListener不能和IIS或IIS Express一起…

git删除本地分支、删除远程分支 复制分支

git删除本地分支、删除远程分支 It_BeeCoder 2019-05-15 09:47:20 80268 收藏 15 展开 https://blog.csdn.net/lihua5419/article/details/81706905 1、查看所有分支 git branch -a 2、查看当前所在分支 git branch 3、删除本地的bug_xzx分支 git branch -d bug_xzx 4…

kotlin能用嵌入式linux,Kotlin在项目中的应用和踩过的坑

应用空类型安全Kotlin引入了可空类型(用&#xff1f;标识)&#xff0c;在编译期杜绝了可空类型直接调用方法的可能。var a: String "abc"a null // 编译错误var b: String? "abc"b null // okval l a.lengthval l b.length // 错误&#xff1a;变量…

ASP.NET Core的Kestrel服务器

Kestrel是一个基于libuv的跨平台ASP.NET Core web服务器&#xff0c;libuv是一个跨平台的异步I/O库。ASP.NET Core模板项目使用Kestrel作为默认的web服务器。 Kestrel支持以下功能&#xff1a; HTTPS用于启用不透明升级的WebSockets位于Nginx之后的高性能Unix sockets Kestrel …

RandomAccessFile

转载自 RandomAccessFile RandomAccessFile是用来访问那些保存数据记录的文件的&#xff0c;你就可以用seek( )方法来访问记录&#xff0c;并进行读写了。这些记录的大小不必相同&#xff1b;但是其大小和位置必须是可知的。但是该类仅限于操作文件。 RandomAccessFile不属于I…

JSR303常见参数

常见参数 NotNull(message "名字不能为空")private String userName;Max(value 120, message "年龄最大不能查过120")private int age;Email(message "邮箱格式错误")private String email;空检查Null 验证对象是否为nullNotNull 验证对象是…

解决:Could not find metadata org.apache.maven.plugins:maven-archetype-plugin/maven-metadata.xml in loc

我的方法 1.电脑可以Google 你要开启那个小飞机 2.笔记本连接手机热点 3.重新操作秒下下来 总结&#xff1a; 公司的网太差 &#xff0c; 也有可能做了外网访问的限制 下面是一个大神的方法 https://blog.csdn.net/Ajax_mt/article/details/81870086 解决:Could n…

Linux 临时表空间满了,Temporary表空间100%解决方案

说明&#xff1a;temp表空间的TS# 为 3*, So TS# 1 4一下是摘自Metalink的说明The DROP_SEGMENTS event~~~~~~~~~~~~~~~~~~~~~~~Available from 8.0 onwards.DESCRIPTIONFinds all the temporary segments in a tablespace which are notcurrently locked and drops them.For t…

Ajax传递json数据

Ajax的传递json数据的实现&#xff1a; 看这篇之前建议大家去看看前面两篇文章&#xff1a; 1.Ajax基本案例详解之$.ajax的实现 2.Ajax基本案例详解之$.get的实现 现在来看一下具体的内容&#xff0c;在index.jsp的<script>里面写&#xff1a; $.ajax({url:"…

ASP.NET Core服务器综述

ASP.NET Core应用通过一个进程内的HTTP服务器实例实现运行&#xff0c;这个服务器实例侦听HTTP请求并将请求作为组成HttpContext的一组请求功能集暴露给我们的应用程序。 ASP.NET Core搭载两个服务器实现&#xff1a; Kestrel是一个基于libuv的跨平台HTTP服务器&#xff0c;lib…

多环境切换---SpringBoot

多环境切换 优先级由高到底&#xff0c;高优先级的配置会覆盖低优先级的配置&#xff1b; profile是Spring对不同环境提供不同配置功能的支持&#xff0c;可以通过激活不同的环境版本&#xff0c;实现快速切换环境&#xff1b; [外链图片转存失败,源站可能有防盗链机制,建议…

Java.io.File.getPath()方法实例

转载自 Java.io.File.getPath()方法实例 java.io.File.getPath() 方法将抽象路径名到路径名字符串。为了分离名称的序列所产生的字符串使用默认名称分隔符。 声明 以下是java.io.File.getPath()方法的声明&#xff1a; public String getPath() String getPath() 参数 NA …

linux中usb设备名,Linux 中识别 USB 设备名字的 4 种方法

摘要&#xff1a; 对于初学者来说&#xff0c;在 Linux 系统里你必须掌握的技术之一就是识别出插入系统里的各种设备。这也许是你的系统硬盘、外部的存储设备或者是可移动设备&#xff0c;比如 USB 设备或 SD 闪存卡等。 现如今&#xff0c;使用 USB 设备来传输文件是十分常见的…

作为 IT 行业的过来人,你有什么话想对后辈说的?

程序员转型 作为 IT 行业的过来人&#xff0c;你有什么话想对后辈说的&#xff1f; - 圆胖肿的回答 - 知乎 https://www.zhihu.com/question/312019918/answer/1246349365 圆胖肿 程序猿 1,644 人赞同了该回答 给资本家做工具人不靠谱&#xff0c;迟早被卷 如果你是男…