三、SpringBoot(3)-原理分析

(该文章整理于网络,仅用于学习记录,如有侵权,请联系删除)

起步依赖原理分析

1. 分析spring-boot-starter-parent

按住Ctrl点击pom.xml中的spring-boot-starter-parent,跳转到了spring-boot-starter-parent的pom.xml,xml配置如下(只摘抄了部分重点配置):

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

按住Ctrl点击pom.xml中的spring-boot-starter-dependencies,跳转到了spring-boot-starter-dependencies的pom.xml,xml配置如下(只摘抄了部分重点配置):

<properties>
  	<activemq.version>5.15.3</activemq.version>
  	<antlr2.version>2.7.7</antlr2.version>
  	<appengine-sdk.version>1.9.63</appengine-sdk.version>
  	<artemis.version>2.4.0</artemis.version>
  	<aspectj.version>1.8.13</aspectj.version>
  	<assertj.version>3.9.1</assertj.version>
  	<atomikos.version>4.0.6</atomikos.version>
  	<bitronix.version>2.1.4</bitronix.version>
  	<build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
  	<byte-buddy.version>1.7.11</byte-buddy.version>
  	... ... ...
</properties>
<dependencyManagement>
  	<dependencies>
      	<dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot</artifactId>
        	<version>2.0.1.RELEASE</version>
      	</dependency>
      	<dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-test</artifactId>
        	<version>2.0.1.RELEASE</version>
      	</dependency>
      	... ... ...
	</dependencies>
</dependencyManagement>
<build>
  	<pluginManagement>
    	<plugins>
      		<plugin>
        		<groupId>org.jetbrains.kotlin</groupId>
        		<artifactId>kotlin-maven-plugin</artifactId>
        		<version>${kotlin.version}</version>
      		</plugin>
      		<plugin>
        		<groupId>org.jooq</groupId>
        		<artifactId>jooq-codegen-maven</artifactId>
        		<version>${jooq.version}</version>
      		</plugin>
      		<plugin>
        		<groupId>org.springframework.boot</groupId>
        		<artifactId>spring-boot-maven-plugin</artifactId>
        		<version>2.0.1.RELEASE</version>
      		</plugin>
          	... ... ...
    	</plugins>
  	</pluginManagement>
</build>

从上面的spring-boot-starter-dependencies的pom.xml中我们可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好,所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了。所以起步依赖的作用就是进行依赖的传递。

2. 分析spring-boot-starter-web

按住Ctrl点击pom.xml中的spring-boot-starter-web,跳转到了spring-boot-starter-web的pom.xml,xml配置如下(只摘抄了部分重点配置):

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  	<modelVersion>4.0.0</modelVersion>
  	<parent>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starters</artifactId>
    	<version>2.0.1.RELEASE</version>
  	</parent>
  	<groupId>org.springframework.boot</groupId>
  	<artifactId>spring-boot-starter-web</artifactId>
  	<version>2.0.1.RELEASE</version>
  	<name>Spring Boot Web Starter</name>
  
  	<dependencies>
    	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter</artifactId>
      		<version>2.0.1.RELEASE</version>
      		<scope>compile</scope>
    	</dependency>
    	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-json</artifactId>
      		<version>2.0.1.RELEASE</version>
      		<scope>compile</scope>
    	</dependency>
    	<dependency>
      		<groupId>org.springframework.boot</groupId>
      		<artifactId>spring-boot-starter-tomcat</artifactId>
      		<version>2.0.1.RELEASE</version>
      		<scope>compile</scope>
    	</dependency>
    	<dependency>
      		<groupId>org.hibernate.validator</groupId>
      		<artifactId>hibernate-validator</artifactId>
      		<version>6.0.9.Final</version>
      		<scope>compile</scope>
    	</dependency>
    	<dependency>
      		<groupId>org.springframework</groupId>
      		<artifactId>spring-web</artifactId>
      		<version>5.0.5.RELEASE</version>
      		<scope>compile</scope>
    	</dependency>
    	<dependency>
      		<groupId>org.springframework</groupId>
      		<artifactId>spring-webmvc</artifactId>
      		<version>5.0.5.RELEASE</version>
      		<scope>compile</scope>
    	</dependency>
  	</dependencies>
</project>

从上面的spring-boot-starter-web的pom.xml中我们可以发现,spring-boot-starter-web就是将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”,这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作用。

自动配置原理解析

按住Ctrl点击查看启动类MySpringBootApplication上的注解@SpringBootApplication

@SpringBootApplication
public class MySpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class);
    }
}

注解@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 {

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * @return the classes to exclude
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	... ... ...

}

其中,

@SpringBootConfiguration:等同与@Configuration,既标注该类是Spring的一个配置类

@EnableAutoConfiguration:SpringBoot自动配置功能开启

按住Ctrl点击查看注解@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
	... ... ...
}

其中,@Import(AutoConfigurationImportSelector.class) 导入了AutoConfigurationImportSelector类

按住Ctrl点击查看AutoConfigurationImportSelector源码

public String[] selectImports(AnnotationMetadata annotationMetadata) {
        ... ... ...
        List<String> configurations = getCandidateConfigurations(annotationMetadata,
                                                                   attributes);
        configurations = removeDuplicates(configurations);
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = filter(configurations, autoConfigurationMetadata);
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return StringUtils.toStringArray(configurations);
}


protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
			AnnotationAttributes attributes) {
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
				getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
		
		return configurations;
}

其中,SpringFactoriesLoader.loadFactoryNames 方法的作用就是从META-INF/spring.factories文件中读取指定类对应的类名称列表

 spring.factories 文件中有关自动配置的配置信息如下:

... ... ...

org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\

... ... ...

上面配置文件存在大量的以Configuration为结尾的类名称,这些类就是存有自动配置信息的类,而SpringApplication在获取这些类名后再加载

我们以ServletWebServerFactoryAutoConfiguration为例来分析源码:

@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
		ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
		ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
		ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
	... ... ...
}

其中,

@EnableConfigurationProperties(ServerProperties.class) 代表加载ServerProperties服务器配置属性类

进入ServerProperties.class源码如下:

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

	/**
	 * Server HTTP port.
	 */
	private Integer port;

	/**
	 * Network address to which the server should bind.
	 */
	private InetAddress address;
  
  	... ... ...
  
}

其中,

prefix = "server" 表示SpringBoot配置文件中的前缀,SpringBoot会将配置文件中以server开始的属性映射到该类的字段中。映射关系如下:

相关推荐

Lambda表达式

codest的专栏 224

inux下C编程(10)---字符及字符串处理

字符编码ASCII: 7位 128个元素。大小写相差20hunicode: 2个 4个或更多的存储空间。utf-8: 每个字符2个字节字符处理库通过转换函数,可以实现和其他类型的转换。字符串转换函数字符串处理函数字符串比较函数字符串查找函数字符串内存函数字符串其他函数...

codest的专栏 233

linux下C编程(09)---函数

函数的一般形式:类型说明可以是任何数据类型,包括vOid.返回语句。return两个作用:结束当前函数,调用者获取程序的控制权。将计算结果传递给调用者。程序结束两种情况:代码结束return作用域规则范围划分局部变量作用函数体内。全局变量。作用域是整个源程序文件,文件中的所有函数和程序块都可以引用。生命周期划分动态存储变量。默认或者AUTO。静态存储变量sttic修饰符函数退出后,变量被保留在内存,再次执行同一函数会得到与上次退出时候相同的数值。函数的.

codest的专栏 231

linux下C编程(08)---数组和指针

一维数组一般形式数据类型 + 名称 +【长度】初始化 3种形式根据下标声明时候加入等号声明时候不指定长度,根据初始化的个数来确定。字符串使用的一维数组字符串数据和一般的字符数据区别是,前者还包含了字符串结束符:“\0”.C没有专门的字符串类型,但是允许使用字符串常量和字符串数组,并提供字符串操作函数。二维数组格式声明:数据类型 + 名称 +【长度1】【长度2】数组长度是 长度1* 长度2二维字符串数组可以看做多个一维字符串数组,第一组是字符串的个数多维数组

codest的专栏 287

linux下C编程(07)---程序控制结构

数据的输入和输出scanf 输入没有专门的语句,通过标准的库函数的调用实现,stdio.hscanf: 键盘上获取,按照指定的输入格式赋给相应的输入项目输入格式格式字符说明d输入一个十进制o输入一个八进制x输入一个16进制f输入一个小数点形式的浮点数e输入一个指数形式的浮点数c输入一个字符s输入一个字符串屏蔽某个数据时候,可以使用修饰符*空格或道和可以表示多个数之间的间隔。printf()输出修饰符是可

codest的专栏 211

linux下C编程(06)---C语言的数据类型

六、C语言的数据类型基本数据类型基本类型字长char 字符型1个字节int 整型2字节 AMD64 下 是4字节float整型4字节double整型8字节void 整型0字节聚合类型数组指针结构体共同体修饰符signedunsignedlongshort修改字符和整数两种基本类型。long还可以用于double.有符号将1位用于存储符号。常量#define定义的常量字符、字符串、数值常量。常量变量枚

codest的专栏 227

2021-09-12

什么是插槽? 插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制 slot官方介绍 Props: name - string,用于命名插槽。 U...

codest的专栏 216

Vue 快速上手

1、前端核心分析2、前端发展史3、第一个Vue程序4、Vue基本语法5、Vue绑定事件6、Vue双向绑定7、Vue组件讲解8、Axios异步通信9、计算属性10、插槽slot11、自定义事件内容分发12、第一个vue-cli程序13、webpack学习使用14、vue-router路由15、vue+elementUl16、路由嵌套17、参数传递及重定向18、404和路由钩子...

codest的专栏 256

若依Vue(若依前后端分离版)--01

介绍RuoYi-Vue 是一个 Java EE 企业级快速开发平台,基于经典技术组合(Spring Boot、Spring Security、MyBatis、Jwt、Vue),内置模块如:部门管理、角色用户、菜单及按钮授权、数据权限、系统参数、日志管理、代码生成等。在线定时任务配置;支持集群,支持多数据源,支持分布式事务。快速了解环境部署部署Java部署Vue项目介绍bbbub{},“aaa”====》debug讲解模拟登陆若依 获取验证码,得到UUID ..

codest的专栏 3996

int与Integer区别及应用场景

一、int与Integer区别:1、int属于基本数据类型,Integer属于int对应的包装类。2、既然是类,就需要实例化才可以使用,而基本数据变量不需要。3、Integer的默认值是null,而int的默认值是0二、int与Integer的应用场景1、为什么java会保留基本数据类型?对于java来说,常说“一切皆对象”,那为啥java还有基本数据类型,对此需要明白,基本数据类型和对象类型的区别1、基本数据类型基本数据类型存在的是:值,基本数据类型在内存中存放的位置是栈。(声明在方法中的

codest的专栏 1548

Java中的List、Set和Map的各自特征及使用场景

Java中的集合分为单列集合Collection和双列集合Map。 先通过这张图看看Collection和Map的各自体系。 首先看单列集合Collection中的List及Set的各自特征。 List(有序,可重复)             ArrayList   &nb...

codest的专栏 551

IDEA 中 Project 和 Module 详解与实战

IDEA 相关文章 标题文章连接大厂通用最全IDEA使用手册https://blog.youkuaiyun.com/chenlixiao007/article/details/106952976阿里巴巴Java开发编码规约与IDEA集成https://blog.youkuaiyun.com/chenlix...

codest的专栏 4777

阿里巴巴Java开发编码规约与IDEA集成

文章目录 IDEA 相关文章Ⅰ 阿里巴巴代码规约插件安装Ⅱ 插件使用Ⅲ 开发规范手册下载 IDEA 相关文章 标题文章连接大厂通用最全IDEA使用手册https://blog.youkuaiyun.com/chenlixiao007/article/details/1069529...

codest的专栏 254

大厂通用最全IDEA使用手册

IDEA 相关文章 标题文章连接阿里巴巴Java开发编码规约与IDEA集成https://blog.youkuaiyun.com/chenlixiao007/article/details/108287646IDEA 创建不同类型 Project 和 Module 详解https://blog.youkuaiyun.com/chenlixiao007/ar...

codest的专栏 543

idea工程和模块的区别

1、工程是独立的,具有自己的内部资源(jar包等)。 模块不是独立的,属于某一个工程,并可以使用该工程的所有资源。2、同一个工程中的模块对于该工程是继承关系,子模块之间初始状态下没有关系。 父工程和子模块之间不用单独手动建立关系,子模块之间需要手动建立关系,各模块之间的关系称为依赖。...

codest的专栏 901

五、SpringBoot(5)-SpringBoot与整合其他技术

SpringBoot整合Mybatis1.1 添加Mybatis的起步依赖<!--mybatis起步依赖--><dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version>&

codest的专栏 220

四、SpringBoot(4)-SpringBoot的配置文件

SpringBoot配置文件类型1 SpringBoot配置文件类型和作用SpringBoot是基于约定的,所以很多配置都有默认值,但如果想使用自己的配置替换默认配置的话,就可以使用application.properties或者application.yml(application.yaml)进行配置。SpringBoot默认会从Resources目录下加载application.properties或application.yml(application.yaml)文件其中,applic

codest的专栏 229

二、SpringBoot(2)--快速入门

代码实现 创建Maven工程 使用idea工具创建一个maven工程,该工程为普通的java工程即可。 添加SpringBoot的起步依赖 编写SpringBoot引导类 编写Controller 测试 快速入门解析 SpringBoot代码解析 SpringBoot工程热部署 使用idea快速创建SpringBoot项目 ...

codest的专栏 222

一、SpringBoot(1)-简介

1.原有Spring优缺点分析1.1 Spring的优点分析Spring是Java企业版(Java Enterprise Edition,JEE,也称J2EE)的轻量级代替品。无需开发重量级的Enterprise JavaBean(EJB),Spring为企业级Java开发提供了一种相对简单的方法,通过依赖注入和面向切面编程,用简单的Java对象(Plain Old Java Object,POJO)实现了EJB的功能。1.2 Spring的缺点分析虽然Spring的组件代码是轻量级的...

codest的专栏 232

Vue的组件为什么要export default

Vue 的模块机制  Vue 是通过 webpack 实现的模块化,因此可以使用 import 来引入模块,例如:  此外,你还可以在 bulid/webpack.base.conf.js 文件中修改相关配置:

codest的专栏 478

vue初学习笔记--01

(该文章仅用于学习记录,如有侵权,请联系删除)

codest的专栏 429

viewport、布局视口、视觉视口、理想视口 深入理解

在移动设备上进行网页的重构或开发,首先得搞明白的就是移动设备上的viewport了,只有明白了viewport的概念以及弄清楚了跟viewport有关的meta标签的使用,才能更好地让我们的网页适配或响应各种不同分辨率的移动设备。通俗的讲,移动设备上的viewport就是设备的屏幕上能用来显示我们的网页的那一块区域,在具体一点,就是浏览器上(也可能是一个app中的webview)用来显示网页的那部分区域,但viewport又不局限于浏览器可视区域的大小,它可能比浏览器的可视区域要大,也可能比浏览器的可视

codest的专栏 769

tp( thinkphp)数据更新和查询

一、数据更新1、使用find方法获取数据,然后通过save方法保存修改,返回布尔值$user = UserModel::find(11); $user->username = '李黑'; $user->save()2、通过where方法解和find方法的查询条件获取的数据进行修改$user=Students::where('id',1)->find();$user->uname ='admin';$user->email ='66461682@qq.

codest的专栏 1092

javascript基础(12)--定时器

333

codest的专栏 116

javascript基础(11)--BOM介绍

BOM:浏览器对象模型,BOM可以使我们通过JS来操作浏览器,在BOM中为我们提供了一组对象,用来完成对浏览器的操作.BOM对象:Window代表的是整个浏览器的窗口,同时window也是网页中的全局对象Navigator代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了一般我们只会使用userAgent来判断浏览器的信息,u.

codest的专栏 116

javascript基础(11)--事件对象

事件对象当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数,在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标键盘哪个按键被按下鼠标滚轮滚动的方向。window.onload = function(){ /* * 当鼠标在areaDiv中移动时,在showMsg中来显示鼠标的坐标 */ //获取两个div var areaDiv = document.getElementById("areaDiv"); var showMsg ...

codest的专栏 221

javascript基础(10)--DOM和事件

DOM:文档对象模型文档:文档表示的就是整个的HTML网页文档 对象:对象表示将网页中的每一个部分都转换为了一个对象,将页面每个元素转换为对象 模型:倒树,体现节点对象之间的关系。 通过js操作html中的元素,如:h1, head等。节点:节点:Node——构成HTML文档最基本的单元 ,常用节点分为四类。文档节点:整个HTML文档 元素节点:HTML文档中的HTML标签 属性节点:元素的属性 文本节点:HTML标签中的文本内容浏览器已经为我们提供文档节点对象..

codest的专栏 302

javascript基础(11)--json

JSON: JavaScriptObjectNotationJS对象表示法JS中的对象只有JS自己认识,其他的语言都不认识,JSON就是一个特殊格式的字符串,这个字符串可以被任意的语言所识别,并且可以转换为任意语言中的对象,JSON在开发中主要用来数据的交互.Json基本语法:JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号,其他的和JS语法一致。对象中的属性名,(注意:单引号、双引号、不加都是可以的)JSON分类:1.对象{} --jso...

codest的专栏 217

javascript基础(9)--正则表达式

正则表达式用于定义一些字符串的规则,计算机可以根据正则表达式,来检查一个字符串是否符合规则,获取将字符串中符合规则的内容提取出来.使用步骤:创建正则表达式的对象 varreg=newRegExp("a"); //对象方式使用字面量:语法:var变量=/正则表达式/匹配模式 这个正则表达式可以来检查一个字符串中是否含有a,在构造函数中可以传递一个匹配模式作为第二个参数,i忽略大小写,g全局匹配模式. 使用TEST() 方法. 使用这个方法可以用来检查一个字符串是...

codest的专栏 150

javascript基础(8)--date /math/包装类/String

1 Date对象在JS中使用Date对象来表示一个时间vard=newDate();vard2=newDate("2/18/201111:10:30");getDate()获取当前日期对象是几日getDay()获取当前日期对象时周几getMonth获取当前时间对象的月份getFullYear * getTime() * - 获取当前日期对象的时间戳 * - 时间戳,指的是从格林威治标准时间的1970年1月1日,0时0...

codest的专栏 101
上一篇: 二、SpringBoot(2)--快速入门
下一篇: 四、SpringBoot(4)-SpringBoot的配置文件
codest
codest 企业官方账号 企业官方账号
博客等级 码龄17年 7粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值