Springboot基础知识(02)- starter 简介和 YAML 配置
1. starter 简介
Spring 项目想要运行,不仅需要导入各种依赖,还要对各种 XML 配置文件进行配置,十分繁琐,但 Spring Boot 项目在创建完成后,即使不编写任何代码,不进行任何配置也能够直接运行,这都要归功于 Spring Boot 的 starter 机制。本节我们将对 stater 进行介绍。
1) starter
Spring Boot 将日常企业应用研发中的各种场景都抽取出来,做成一个个的 starter(启动器),starter 中整合了该场景下各种可能用到的依赖,用户只需要在 Maven 中引入 starter 依赖,SpringBoot 就能自动扫描到要加载的信息并启动相应的默认配置。
starter 提供了大量的自动配置,让用户摆脱了处理各种依赖和配置的困扰。所有这些 starter 都遵循着约定成俗的默认配置,并允许用户调整这些配置,即遵循 “约定大于配置” 的原则。
并不是所有的 starter 都是由 Spring Boot 官方提供的,也有部分 starter 是第三方技术厂商提供的,例如 druid-spring-boot-starter 和 mybatis-spring-boot-starter 等等。当然也存在个别第三方技术,Spring Boot 官方没提供 starter,第三方技术厂商也没有提供 starter。
以 spring-boot-starter 为例,它能够为提供命令行程序开发场景所需要的几乎所有依赖,因在使用 Spring Boot 开发命令行项目时,只需要引入该 Starter 不需要其它依赖。
在 pom.xml 中引入 spring-boot-starter,示例代码如下。
1 <project ... > 2 ... 3 4 <parent> 5 <groupId>org.springframework.boot</groupId> 6 <artifactId>spring-boot-starter-parent</artifactId> 7 <version>2.6.6</version> 8 <relativePath/> <!-- lookup parent from repository --> 9 </parent> 10 11 <dependencies> 12 13 ... 14 15 <dependency> 16 <groupId>org.springframework.boot</groupId> 17 <artifactId>spring-boot-starter</artifactId> 18 </dependency> 19 20 ... 21 22 </dependencies> 23 24 ... 25 26 </project>
在该项目中执行以下 mvn 命令查看器依赖树。
mvn dependency:tree
执行结果如下:
1 [INFO] 2 [INFO] --------------------< com.example:SpringbootBasic >--------------------- 3 [INFO] Building SpringbootBasic 1.0-SNAPSHOT 4 [INFO] --------------------------------[ jar ]--------------------------------- 5 [INFO] 6 [INFO] --- maven-dependency-plugin:3.2.0:tree (default-cli) @ SpringbootBasic --- 7 [INFO] com.example:SpringbootBasic:jar:1.0-SNAPSHOT 8 [INFO] +- org.springframework.boot:spring-boot-starter:jar:2.6.6:compile 9 [INFO] | +- org.springframework.boot:spring-boot:jar:2.6.6:compile 10 [INFO] | | \- org.springframework:spring-context:jar:5.3.18:compile 11 [INFO] | | +- org.springframework:spring-aop:jar:5.3.18:compile 12 [INFO] | | +- org.springframework:spring-beans:jar:5.3.18:compile 13 [INFO] | | \- org.springframework:spring-expression:jar:5.3.18:compile 14 [INFO] | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.6.6:compile 15 [INFO] | +- org.springframework.boot:spring-boot-starter-logging:jar:2.6.6:compile 16 [INFO] | | +- ch.qos.logback:logback-classic:jar:1.2.11:compile 17 [INFO] | | | \- ch.qos.logback:logback-core:jar:1.2.11:compile 18 [INFO] | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.17.2:compile 19 [INFO] | | | \- org.apache.logging.log4j:log4j-api:jar:2.17.2:compile 20 [INFO] | | \- org.slf4j:jul-to-slf4j:jar:1.7.36:compile 21 [INFO] | +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile 22 [INFO] | +- org.springframework:spring-core:jar:5.3.18:compile 23 [INFO] | | \- org.springframework:spring-jcl:jar:5.3.18:compile 24 [INFO] | \- org.yaml:snakeyaml:jar:1.29:compile 25 [INFO] +- org.springframework.boot:spring-boot-starter-test:jar:2.6.6:test 26 [INFO] | +- org.springframework.boot:spring-boot-test:jar:2.6.6:test 27 [INFO] | +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.6.6:test 28 [INFO] | +- com.jayway.jsonpath:json-path:jar:2.6.0:test 29 [INFO] | | +- net.minidev:json-smart:jar:2.4.8:test 30 [INFO] | | | \- net.minidev:accessors-smart:jar:2.4.8:test 31 [INFO] | | | \- org.ow2.asm:asm:jar:9.1:test 32 [INFO] | | \- org.slf4j:slf4j-api:jar:1.7.36:compile 33 [INFO] | +- jakarta.xml.bind:jakarta.xml.bind-api:jar:2.3.3:test 34 [INFO] | | \- jakarta.activation:jakarta.activation-api:jar:1.2.2:test 35 [INFO] | +- org.assertj:assertj-core:jar:3.21.0:test 36 [INFO] | +- org.hamcrest:hamcrest:jar:2.2:test 37 [INFO] | +- org.junit.jupiter:junit-jupiter:jar:5.8.2:test 38 [INFO] | | +- org.junit.jupiter:junit-jupiter-api:jar:5.8.2:test 39 [INFO] | | | +- org.opentest4j:opentest4j:jar:1.2.0:test 40 [INFO] | | | +- org.junit.platform:junit-platform-commons:jar:1.8.2:test 41 [INFO] | | | \- org.apiguardian:apiguardian-api:jar:1.1.2:test 42 [INFO] | | +- org.junit.jupiter:junit-jupiter-params:jar:5.8.2:test 43 [INFO] | | \- org.junit.jupiter:junit-jupiter-engine:jar:5.8.2:test 44 [INFO] | | \- org.junit.platform:junit-platform-engine:jar:1.8.2:test 45 [INFO] | +- org.mockito:mockito-core:jar:4.0.0:test 46 [INFO] | | +- net.bytebuddy:byte-buddy:jar:1.11.22:test 47 [INFO] | | +- net.bytebuddy:byte-buddy-agent:jar:1.11.22:test 48 [INFO] | | \- org.objenesis:objenesis:jar:3.2:test 49 [INFO] | +- org.mockito:mockito-junit-jupiter:jar:4.0.0:test 50 [INFO] | +- org.skyscreamer:jsonassert:jar:1.5.0:test 51 [INFO] | | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test 52 [INFO] | +- org.springframework:spring-test:jar:5.3.18:test 53 [INFO] | \- org.xmlunit:xmlunit-core:jar:2.8.4:test 54 [INFO] \- junit:junit:jar:4.11:test 55 [INFO] \- org.hamcrest:hamcrest-core:jar:2.2:test 56 [INFO] ------------------------------------------------------------------------ 57 [INFO] BUILD SUCCESS 58 [INFO] ------------------------------------------------------------------------ 59 [INFO] Total time: 13.963 s 60 [INFO] Finished at: 2022-04-03T21:09:48+08:00 61 [INFO] ------------------------------------------------------------------------
从以上结果中,我们可以看到 Spring Boot 导入了 springframework、logging 等依赖,而这些是命令行项目所需要的。
在以上 pom.xml 的配置中,引入依赖 spring-boot-starter 时,并没有指明其版本(version),但在依赖树中,却看到所有的依赖都具有版本信息,那么这些版本信息是在哪里控制的呢?
这些版本信息是由 spring-boot-starter-parent(版本仲裁中心) 统一控制的。
2) spring-boot-starter-parent
spring-boot-starter-parent 是所有 Spring Boot 项目的父级依赖,它被称为 Spring Boot 的版本仲裁中心,可以对项目内的部分常用依赖进行统一管理。
1 <!-- SpringBoot 父项目依赖管理 --> 2 <parent> 3 <groupId>org.springframework.boot</groupId> 4 <artifactId>spring-boot-starter-parent</artifactId> 5 <version>2.6.6</version> 6 <relativePath/> 7 </parent>
Spring Boot 项目可以通过继承 spring-boot-starter-parent 来获得一些合理的默认配置,它主要提供了以下特性:
(1) 默认 JDK 版本(Java 8)
(2) 默认字符集(UTF-8)
(3) 依赖管理功能
(4) 资源过滤
(5) 默认插件配置
(6) 识别 application.properties 和 application.yml 类型的配置文件
查看 spring-boot-starter-parent 的底层代码,可以发现其有一个父级依赖 spring-boot-dependencies。
1 <parent> 2 <groupId>org.springframework.boot</groupId> 3 <artifactId>spring-boot-dependencies</artifactId> 4 <version>2.6.6</version> 5 </parent>
spring-boot-dependencies 的底层代码如下。
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" 4 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 5 <modelVersion>4.0.0</modelVersion> 6 <groupId>org.springframework.boot</groupId> 7 <artifactId>spring-boot-dependencies</artifactId> 8 <version>2.4.5</version> 9 <packaging>pom</packaging> 10 .... 11 <properties> 12 <activemq.version>5.16.1</activemq.version> 13 <antlr2.version>2.7.7</antlr2.version> 14 <appengine-sdk.version>1.9.88</appengine-sdk.version> 15 <artemis.version>2.15.0</artemis.version> 16 <aspectj.version>1.9.6</aspectj.version> 17 <assertj.version>3.18.1</assertj.version> 18 <atomikos.version>4.0.6</atomikos.version> 19 .... 20 </properties> 21 <dependencyManagement> 22 <dependencies> 23 <dependency> 24 <groupId>org.apache.activemq</groupId> 25 <artifactId>activemq-amqp</artifactId> 26 <version>${activemq.version}</version> 27 </dependency> 28 <dependency> 29 <groupId>org.apache.activemq</groupId> 30 <artifactId>activemq-blueprint</artifactId> 31 <version>${activemq.version}</version> 32 </dependency> 33 ... 34 </dependencies> 35 </dependencyManagement> 36 <build> 37 <pluginManagement> 38 <plugins> 39 <plugin> 40 <groupId>org.codehaus.mojo</groupId> 41 <artifactId>build-helper-maven-plugin</artifactId> 42 <version>${build-helper-maven-plugin.version}</version> 43 </plugin> 44 <plugin> 45 <groupId>org.flywaydb</groupId> 46 <artifactId>flyway-maven-plugin</artifactId> 47 <version>${flyway.version}</version> 48 </plugin> 49 ... 50 </plugins> 51 </pluginManagement> 52 </build> 53 </project>
以上配置中,部分元素说明如下:
dependencyManagement :负责管理依赖;
pluginManagement:负责管理插件;
properties:负责定义依赖或插件的版本号。
spring-boot-dependencies 通过 dependencyManagement 、pluginManagement 和 properties 等元素对一些常用技术框架的依赖或插件进行了统一版本管理,例如 Activemq、Spring、Tomcat 等。
2. YAML 配置
Spring Boot 提供了大量的自动配置,极大地简化了 spring 应用的开发过程,当用户创建了一个 Spring Boot 项目后,即使不进行任何配置,该项目也能顺利的运行起来。当然,用户也可以根据自身的需要使用配置文件修改 Spring Boot 的默认设置。
SpringBoot 默认使用以下 2 种全局的配置文件,其文件名是固定的。
application.properties
application.yml
其中,application.yml 是一种使用 YAML 语言编写的文件,它与 application.properties 一样,可以在 Spring Boot 启动时被自动读取,修改 Spring Boot 自动配置的默认值。
本文将详细介绍 YAML 语言的语法及使用。
1) YAML 简介
YAML 全称 YAML Ain't Markup Language,它是一种以数据为中心的标记语言,比 XML 和 JSON 更适合作为配置文件。
想要使用 YAML 作为属性配置文件(以 .yml 或 .yaml 结尾),需要将 SnakeYAML 库添加到 classpath 下,Spring Boot 中的 spring-boot-starter-web 或 spring-boot-starter 都对 SnakeYAML 库做了集成, 只要项目中引用了这两个 Starter 中的任何一个,Spring Boot 会自动添加 SnakeYAML 库到 classpath 下。
下面是一个简单的 application.yml 属性配置文件。
server:
port: 9090
2) YAML 语法
YAML 的语法如下:
(1) 使用缩进表示层级关系。
(2) 缩进时不允许使用 Tab 键,只允许使用空格。
(3) 缩进的空格数不重要,但同级元素必须左侧对齐。
(4) 大小写敏感。
例如:
1 spring: 2 profiles: dev 3 4 datasource: 5 url: jdbc:mysql://127.0.0.1/springboot_basic 6 username: root 7 password: root 8 driver-class-name: com.mysql.jdbc.Driver
3) YAML 常用写法
(1) YAML 对象写法
在 YAML 中,对象可能包含多个属性,每一个属性都是一对键值对。
YAML 为对象提供了 2 种写法:
普通写法,使用缩进表示对象与属性的层级关系。
website:
name: spring
url: spring.io
单行写法:
website: {name: spring, url: spring.io}
(2) YAML 数组写法
YAML 使用 “-” 表示数组中的元素,普通写法如下:
pets:
-dog
-cat
-chick
单行写法:
pets: [dog,cat,chick]
(3) YAML 字面量写法
字面量是指单个的,不可拆分的值,例如:数字、字符串、布尔值、以及日期等。
在 YAML 中,使用 “key:[空格]value” 的形式表示一对键值对(空格不能省略),如 spring.io
字面量直接写在键值对的 “value” 中即可,且默认情况下字符串是不需要使用单引号或双引号的。
name: spring
若字符串使用单引号,则会转义特殊字符。
name: 'spring \n boot'
输出结果为:
spring \n boot
若字符串使用双引号,则不会转义特殊字符,特殊字符会输出为其本身想表达的含义
name: "spring \n boot"
输出结果为:
spring
boot
(4) 复合结构
以上三种数据结构可以任意组合使用,以实现不同的用户需求,例如:
1 person: 2 name: spring 3 age: 30 4 pets: 5 -dog 6 -cat 7 -chick 8 child: 9 name: springboot 10 age: 5
4) YAML 组织结构
一个 YAML 文件可以由一个或多个文档组成,文档之间使用 "---" 作为分隔符,且个文档相互独立,互不干扰。如果 YAML 文件只包含一个文档,则 "---" 分隔符可以省略。
1 --- 2 website: 3 name: spring 4 url: spring.io 5 --- 6 website: {name: spring, url: spring.io} 7 pets: 8 -dog 9 -cat 10 -chick 11 --- 12 pets: [dog,cat,chick] 13 name: "spring \n boot" 14 --- 15 name: 'spring \n boot'