目录
1. Spring Boot 项目中配日文件的作用是什么
2. Spring Boot 配置文件的两种格式
3. properties 配置文件
3.1 properties 配置文件的基本语法
3.2 properties 配置文件的分类
3.3 如何读取配置文件
3.4 properties 配置文件的优缺点分析
4. yml 配置文件
4.1 yml 的基本语法
4.2 yml 配置文件的优点
4.3 yml 配置基本数据类型
4.4 yml 配置对象
4.5 yml 读取对象
4.6 yml 配置集合
5. 设置多平台的配置文件
1. Spring Boot 项目中配日文件的作用是什么
配置文件中最主要的两个作用: 连接数据库和用于定位问题的关键日志.
一个项目中没有数据库的话那就谈不上一个完整的项目,假如今天王者出新皮肤了, 你心智勃勃花了一千多块钱买了好几款喜欢的皮肤, 没有数据库的话, 过两天你上线发现皮肤没了, 你心里肯定有一万只 XXX 奔腾而过. 如果没有配置文件 , 程序出问题, 很难查找时, 都无法定位到关键日志, 所以配置文件还是相当的重要的.
配置文件的作用:
- 连接数据库的信息
- 用于发现和定位问题的关键日志
- 设置项目的启动端口
- 第三方系统的调用密钥等信息 (例如老师在某平台给我们上课时, 他能在平台上拿到我们的数据, 就是通过配置文件中设置的标识来调用第三方接口获取的)
2. Spring Boot 配置文件的两种格式
Spring Boot 中有两种格式的配置文件:
- properties (application.properties)
- yml (application.yml)
Spring Boot 中这两种格式的配置文件的命名方式必须以 application 开头, 否则配置就不会生效, 这就牵扯到了高级框架中的 "约定大于配置" , 我们要做的事情越来越少了, 但是要遵守的约定越来越多了.
【问题】为什么需要两种格式的配置文件呢 ? 仅仅是为了提供更多的选择 ?
1. yml 相比于 properties 在写法上简化了许多 (后面会演示代码)
2. 在跨平台等问题上也是有很大的优势 (后面会讲到)
【问题】两种格式的配置文件如果同时存在, 会以哪种格式为主?
1. 当一个项目中出现了两种格式的配置文件时, properties 格式的配置文件优先级高, 所以会以 properties 格式的配置文件为主. 例如 properties 配置文件中设置了端口为 8081, .yml 配置文件中也设置了端口, 为 8082, 那么最终程序启动时的端口就是 8081, 但是加载完 properties 文件之后, 也会加载 .yml 文件中的配置信息.
2.理论上是这两种格式的配置文件可以出现在一个项目中, 但是一般都会统一配置文件,如果两种格式都写了, 可能会有增加排查问题的风险; 就好比衣服种类有很多, 但是一个餐厅里的服务员一般都会统一服装, 否则会显得杂乱无章, 不正式.
3. properties 配置文件
3.1 properties 配置文件的基本语法
# 设置端口号
server.port=8081
#设置数据库的连接信息
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/book?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
properties 配置文件中是以键值对的格式进行配置的, "key" 和 "value" 通过 "=" 来连接.
更多系统配置: Spring Boot 中更多系统配置
【整个花活】通过配置文件来设置 Spring Boot 项目启动的 log:
1. 在 resource 文件夹下创建一个 banner.txt 文件, 命名必须是 banner.txt , 否则读取不到.
2. 把你想要的 log 复制进去, 然后启动 IDEA 就能看到.
下载 log 相关网址 : https://www.bootschool.net/ascii-art
效果图:
3.2 properties 配置文件的分类
1. Spring Boot 内置的配置项, 比如 server.port, 等等...
2. 用户自定义的配置项: mykey.key1=zhangsan, mykey.key2=lisi .....
# 设置端口号
server.port=8081
# 用户自定义的配置项
mykey.key1=zhangsan
mykey.key2=lisi
3.3 如何读取配置文件
通过使用 @Value 注解来实现, 基本格式:
@Value("${server.port}")
【代码示例】
自定义配置项:
key1=zhangsan
key2=lisi
读取配置文件:
@RestController
public class TestController {
// 读取自定义配置项
@Value("key1")
private String key1;
// 读取系统配置项
@Value("${server.port}")
private Integer port;
@RequestMapping("/key")
public String readKey() {
return "key1: " + key1 + " | port: " + port;
}
}
运行程序, 此时在浏览器输入 URL, 就能拿到相关 key 对应的 value 值。
【注意事项】
还是那句话, "约定大于配置", 我们一定要遵守这种写法: ${}, 如果我们写成这样 @Value("key1"), 那么读取的时候, 虽然不会报错, 但是它会将 key1 当做字符串赋值给 key1, 那么此时你再运行程序, 就会输出以下结果, 就拿不到自定义配置中 key 对应的 value 值了.
3.4 properties 配置文件的优缺点分析
【优点】
- 格式简单, 不易出错.
- 写法上更加直观
【缺点】
- 写法不够灵活, 不够简便, 例如下面的数据库相关配置, 同样的前缀信息, 需要写多遍.
- 乱码问题:
使用 properties 格式的配置文件, 我们加注释的中文, 以及头比较铁的时候, 给键或值写成中文的时候, 我们关闭项目后再打开项目时, 这些中文就会乱码; 甚至是我没关闭项目, 我通过 @Value 等注解的方式去读的时候, 也有可能出现乱码的问题,而且是不可逆的, 因为 IDEA 会默认给 properties 配置文件设置 IOS-8859-1 的编码格式. 而 yml 格式的配置文件就不存在这个问题, 它默认是 UTF-8 的编码格式.
如何解决 propeties 配置文件乱码问题:
第一步: 进入当前项目的 settings 和 新项目的 settings
第二步: 按照下图的方式去更改当前项目的 settings 和新项目的 settings.
4. yml 配置文件
yml 是 YAML 的缩写, 全称 -> Yet Another Markup Language. 中文意思为 "另一种语言".
4.1 yml 的基本语法
yml 不像 properties 那中键值对的方式, 而是树形结构的格式, 基本格式 :
写法规范注意:
- 一级目录下: 键和值之间的冒号后面要有空格, 千万不能省略!!
- 多级目录下: 从第二级目录开始, 相较于上一级目录, 最前面要带有 tab 键
对比数据库连接的写法后, 发现 yml 的写法省略了重复的前缀信息, 写法上更加简便了.
单从写法简便这一点上来说, yml 还不足以打败 properties, 那么下面来分析 yml 还有哪些优点:
4.2 yml 配置文件的优点
1. yml 可读性高, 写法上相较于 properties 更加简洁的, 语法和 JSON 高度相似.
2. yml 支持更多的数据类型, 它不仅支持基本数据类型, 它还可以表达数组, 散列表, 标量等数据形态, 还特别适合用来表达数据结构(各种集合), 各种配置文件等等.
3. yml 支持更多的编程语言, 它是跨语言的, 它不仅仅只是在 Java 中可以使用, 还可以在 Golang, PHP, Python, Ruby, JavaScript 等语言中使用. (质的提升)
4.3 yml 配置基本数据类型
前边演示了 String 类型, 其他像 boolean, int, float, 甚至 null 都是 类似的.
【代码示例】
# 布尔类型
boolean: false
# 整数
int.value1: 20
int.value2: 0b1010_0111_0100_1010_11010 # 二进制
# 浮点型
float.value: 3.14
# null
null.value: ~
yml 配置 String 类型注意事项:
yml 在配置 String 类型的时候有三种写法
- 默认不用加单双引号
- 加单引号
- 加双引号
【代码示例】
yml 配置文件
读取配置文件(和 properties 相同)
@RestController
public class TestController {
@Value("${key2}")
private String key2;
@Value("${String.str1}")
private String str1;
@Value("${String.str2}")
private String str2;
@Value("${String.str3}")
private String str3;
@RequestMapping("/key")
public String readKey() {
System.out.println();
System.out.println("String.str1: " + str1);
System.out.println("String.str2: " + str2);
System.out.println("String.str3: " + str3);
return "key2: " + key2;
}
}
运行结果:
【结论】
1. 字符串默认不⽤加上单引号或者双引号.2. 单引号会转义特殊字符,特殊字符最终只是⼀个普通的字符串数据.3. 双引号不会转义字符串⾥⾯的特殊字符;特殊字符会作为本身想表示的意思.
4.4 yml 配置对象
yml 配置对象有两种写法: 1. 原始写法 2. 行内写法
1. 原始写法:
student:
id: 1
name: zhangsan
age: 18
2. 行内写法:
student: {id: 1,name: zhangsan,age: 18}
4.5 yml 读取对象
读取对象的时候, 我们不再使用 @Value("${}") 注解了, 因为这个注解每次只能读到一个 value, 如果我们要读的对象有一百个属性, 我们是不可能去写一百遍重复的代码的. 此时我们需要使用到 @ConfigurationProperties 注解来实现.
基本格式:
@ConfigurationProperties(prefix = "student")
【代码示例】 读取上述 student 对象
Bean 对象
@Data
@Component
@ConfigurationProperties(prefix = "student")
// 读取 yml 中的 student 属性, 赋值给 Student 对象
public class Student {
private Integer id;
private String name;
private Integer age;
}
@ConfigurationProperties 注解的作用就是从 yml 中读取 student 属性, 然后复制给 bean 对象.
@RestController
public class TestController {
@Autowired
private Student student;
@RequestMapping("/student")
public String readKey() {
return "userId: " + student.getId() +
" | userName: " + student.getName();
}
}
运行程序, 通过 url 访问:
yml 读取对象的注意事项
1. yml 配置对象的时候, 键名不能出现大写, 也不能出现下划线, 只能小写或者写成 stu-name.
2. 读取配置文件的实体类不能没有 setter 方法, @ConfigurationProperties 注解在实现时是通过 setter 将配置文件中的内容赋值给字段的. (可以通过 Generate 生成 Getter 和 Setter 方法, 或者通过 lombok 中的 @Data 注解来设置)
3. @ConfigurationProperties 需要配置五大类注解使用.
4.6 yml 配置集合
yml 配置集合也有两种格式: 1. 原始写法 2.行内写法
1. 原始写法
mylist:
dbtype:
- mysql
- sqlserver
- db2
2. 行内写法
mylist: {dbtype: [mysql,sqlserver,db2]}
4.7 yml 读取集合
yml 读取集合和读取对象的方式是类似的, 也是通过 @ConfigurationProperties 注解来实现的.
【代码示例】读取上述 mylist 集合
Bean 对象
@Data
@Component
@ConfigurationProperties(prefix = "mylist2")
public class MyList {
private List<String> dbtype; // 泛型可加可不加
}
读取集合:
@RestController
public class TestController {
@Autowired
private MyList mylist;
@RequestMapping("/student")
public String readKey() {
return "list-Size: " + mylist.getDbtype().size()
+ " | list.get(0): " + mylist.getDbtype().get(0);
}
}
启动服务器, 浏览器输入 url :
5. 设置多平台的配置文件
对于公司级别的环境而言, 最小的公司一般都会分三种环境来进行管理:
多平台配置文件设置
- 开发环境的配置文件 [application-dev.yml]
- 测试环境的配置文件 [application-text.yml]
- 生产环境的配置文件 [application-prod.yml]
【注意】不同环境配置文件的命名必须以 application- 开头
【如何设置多平台的配置文件】
1. 使用一份 yml 配置文件, 不同的环境, 通过修改和注释来解决.(麻烦)
就拿数据库连接来说, 假如我连接的是开发环境的数据库, 我数据库的信息写好了, 我下次再连接测试环境的数据库, 我又把开发环境的数据库的相关信息给注释掉, 再去写我连接测试数据库的信息. 这样会面临两个问题:
- 极端一点来说, 万一我配置文件连接了生产环境上的数据库, 我手动修改, 就总是会有改错的风险的, 如果改错了, 就会污染生产环境的库.
- 第二, 不同环境的配置可能会非常繁琐, 改来改去有时候可能不止改一点点代码, 难度太大.
2. 不同的运行环境, 设置不同的配置文件.(更优)
而我们使用不同环境对应不同的配置文件, 这样就优雅方便很多了, 我不同的环境, 有着不同的代码, 不需要去修改, 只需要在主配置文件中去设置它需要运行的平台就行了.所以我们一般都是主配置文件搭配我们所需要的配置环境一起去使用的.
【代码示例】
测试环境配置文件 application-test.yml
server:
port: 7777
Spring:
datasource:
url: jdbc:mysql://yyyy:3306/book?characterEncoding=utf8
username: root
password: aaaaa
开发环境配置文件 application-prod.yml
server:
port: 8888
Spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/book?characterEncoding=utf8
username: root
password: 123456
生产环境配置文件 application-prod.yml
server:
port: 9999
Spring:
datasource:
url: jdbc:mysql://xxxx:3306/book?characterEncoding=utf8
username: root
password: bbbbbb
在主配置文件中设置运行环境:
# 运行环境设置
Spring:
profiles:
active: prod
active 后面写 prod, test 和 dev, 就表示当前主配置文件要搭配那个运行环境来使用.
以生产环境为例, 启动程序, 观察端口号来区别运行环境.
- 7777: 测试环境
- 8888: 开发环境
- 9999: 生产环境
观察结果可以对应上当前环境是生产环境, 测试环境和开发环境都是类似的做法.