SpringBoot配置文件是什么?该如何使用?
一、前言
前面我们讲解了SpringBoot到底是什么?如何理解parent、starter、引导类以及内嵌Tomcat?我们可以了解parent
、starter
、引导类
、以及内嵌Tomcat
相关的知识!今天让我们来看看SpringBoot基础配置。
二、问题引入
我们发现SpringBoot几乎不用做任何的配置,功能就有了,确实很好用。但是仔细想想,没有做配置意味着什么?意味着配置已经做好了,不用你自己写了。但是新的问题又来了,如果不想用已经写好的默认配置,该如何干预呢?这就是这一篇博客咱们要研究的问题。
三、属性配置
当我们创建一个新的springboot工程,在resources资源
目录下,就会自动创建一个application.properties
文件,结构如下图所示,所以就先从它开始吧!
从最简单的开始吧!大家都知道,我们使用的Tomcat服务器,它的默认端口是8080,我现在想修改为80端口,方便后续的测试更加的简便。该如何修改呢?
答案其实很简单,进入application.properties
文件,输入port
关键字,可以发现IDEA开发工具会自动给我关于端口修改的提示,enter
选择就可以了。
文件代码如下:
server.port=80
运行一下看看结果,如下图所示,结果是80端口,完全正确
做完了端口的配置,趁热打铁,再做几个配置,目前项目启动时会显示一些日志信息,就来改一改这里面的一些设置。
关闭运行日志图表(banner)
spring.main.banner-mode=off
设置运行日志的显示级别
logging.level.root=info
我们现在配置了3个信息,但是又有新的问题了。这个配置是随便写的吗?什么都能配?有没有一个东西显示所有能配置的项呢?此外这个配置和什么东西有关呢?会不会因为我写了什么东西以后才可以写什么配置呢?比如我现在没有写数据库相关的东西,能否配置数据呢?
打开SpringBoot的官网,找到SpringBoot官方文档,打开查看附录中的Application Properties
就可以获取到对应的配置项了,网址奉上:Common Application Properties
能写什么的问题解决了,再来说第二个问题,这个配置项和什么有关。在pom
中注释掉导入的spring-boot-starter-web
,然后刷新工程,你会发现配置的提示消失了。原来是设定使用了什么技术才能做什么配置。
温馨提示
所有的starter中都会依赖下面这个starter,叫做spring-boot-starter
。这个starter是所有的SpringBoot的starter的基础依赖,里面定义了SpringBoot相关的基础配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.5.4</version>
<scope>compile</scope>
</dependency>
四、配置文件分类
SpringBoot除了支持properties格式的配置文件,还支持另外两种格式的配置文件。分别如下:
- properties格式
- yml格式
- yaml格式
就拿修改端口号为例,看看三种配置文件的特点:
application.properties(==properties格式==)
server.port=80
- application.yml(==yml格式==)
server:
port: 81
- application.yaml(==yaml格式==)
server:
port: 82
仔细看会发现yml
格式和yaml
格式除了文件名后缀不一样,格式完全一样。yml
和yaml
文件格式是一模一样的,只是文件后缀不同,所以可以合并成一种格式来看。那对于这三种格式来说,以后用哪一种比较多呢?以后基本上都是用yml
格式的,以后在企业开发过程中用这个格式的机会也最多,一定要重点掌握。
五、配置文件优先级
现在我们已经知道使用三种格式都可以做配置了,好奇友友们就会问了,万一我三个都写了,他们三个谁说了算呢?
其实三个文件如果共存的话,谁生效说的就是配置文件加载的优先级别。我们就让三个配置文件书写同样的信息,比如都配置端口,然后我们让每个文件配置的端口号都不一样,最后启动程序后看启动端口是多少就知道谁的加载优先级比较高了。
- application.properties(==properties格式==)
server.port=80
- application.yml(==yml格式==)
server:
port: 81
- application.yaml(==yaml格式==)
server:
port: 82
启动后发现目前的启动端口为80,把80对应的文件删除掉,然后再启动,现在端口又改成了81。现在我们就已经知道了3个文件的加载优先顺序是什么
application.properties > application.yml > application.yaml
虽然得到了一个知识结论,但是我们实际开发的时候还是要看最终的效果为准。也就是你要的最终效果是什么自己是明确的,上述结论只能帮助你分析结论产生的原因。这个知识了解一下就行了,因为以后同时写多种配置文件格式的情况实在是较少。
最后我们把配置文件内容给修改一下
- application.properties(==properties格式==)
server.port=80
spring.main.banner-mode=off
- application.yml(==yml格式==)
server:
port: 81
logging:
level:
root: debug
- application.yaml(==yaml格式==)
server:
port: 82
我们发现不仅端口生效了,最终显示80,同时其他两条配置也生效了,看来每个配置文件中的项都会生效,只不过如果多个配置文件中有相同类型的配置会优先级高的文件覆盖优先级的文件中的配置。如果配置项不同的话,那所有的配置项都会生效。
总结
- 配置文件间的加载优先级 properties(最高)> yml > yaml(最低)
- 不同配置文件中相同配置按照加载优先级相互覆盖,不同配置文件中不同配置全部保留
六、语法介绍
YAML(YAML Ain't Markup Language)
,一种数据序列化格式。具有容易阅读、容易与脚本语言交互、以数据为核心,重数据轻格式的特点。常见的文件扩展名有两种:
-
.yml格式(主流)
-
.yaml格式
对于文件自身在书写时,具有严格的语法格式要求,具体如下:
- 大小写敏感
- 属性层级关系使用多行描述,每行结尾使用冒号结束
- 使用缩进表示层级关系,同层级左侧对齐,只允许使用空格(不允许使用Tab键)
- 属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
- #号 表示注释
上述规则不要死记硬背,按照书写习惯慢慢适应,并且在Idea下由于具有提示功能,慢慢适应着写格式就行了。核心的一条规则要记住,数据前面要加空格与冒号隔开
下面列出常见的数据书写格式,熟悉一下
boolean: TRUE #TRUE,true,True,FALSE,false,False均可
float: 3.14 #6.8523015e+5 #支持科学计数法
int: 123 #0b1010_0111_0100_1010_1110 #支持二进制、八进制、十六进制
null: ~ #使用~表示null
string: HelloWorld #字符串可以直接书写
string2: "Hello World" #可以使用双引号包裹特殊字符
date: 2018-02-17 #日期必须使用yyyy-MM-dd格式
datetime: 2018-02-17T15:02:31+08:00 #时间和日期之间使用T连接,最后使用+代表时区
此外,yaml格式中也可以表示数组,在属性名书写位置的下方使用减号作为数据开始符号,每行书写一个数据,减号与数据间空格分隔
subject:
- Java
- 前端
- 大数据
enterprise:
name: itcast
age: 16
subject:
- Java
- 前端
- 大数据
likes: [王者荣耀,刺激战场] #数组书写缩略格式
users: #对象数组格式一
- name: Tom
age: 4
- name: Jerry
age: 5
users: #对象数组格式二
-
name: Tom
age: 4
-
name: Jerry
age: 5
users2: [ { name:Tom , age:4 } , { name:Jerry , age:5 } ] #对象数组缩略格式
现在我们已经知道了yaml具有严格的数据格式要求,并且已经可以正确的书写yaml文件了,那这些文件书写后其实是在定义一些数据。这些数据时给谁用的呢?大部分是SpringBoot框架内部使用,但是如果我们想配置一些数据自己使用,能不能用呢?答案是可以的,那如何读取yaml文件中的数据呢?
七、数据读取
对于yaml文件中的数据,其实你就可以想象成这就是一个小型的数据库,里面保存有若干数据,每个数据都有一个独立的名字,如果你想读取里面的数据,肯定是支持的,下面就介绍3种读取数据的方式
为了方便测试,先看看我在配置文件中写的测试数据内容
1、读取单一数据
yaml中保存的单个数据,可以使用Spring中的注解直接读取,使用@Value可以读取单个数据,属性名引用方式:${一级属性名.二级属性名……}
写一个代码测试一下:
@RestController
@RequestMapping("/books")
public class BookController {
//yml读取单一数据
@Value("${country}")
private String country;
//对象的某个属性值
@Value("${user1.name}")
private String name;
//普通数组的某个值
@Value("${hobby[0]}")
private String hobby;
//对象数组的某个属性的值
@Value("${users[0].name}")
private String age;
@GetMapping("/getBooks")
public String getBooks() {
System.out.println("SpringBoot 正在运行~");
System.out.println("单一数据country是:" + country);
System.out.println("对象的某个属性值是:" + name);
System.out.println("普通数组的某个值是:" + hobby);
System.out.println("对象数组的某个属性的值是:" + age);
return "Hello,SpringBoot is running";
}
}
运行结果完全正确!
2、读取全部数据
读取单一数据可以解决读取数据的问题,但是如果定义的数据量过大,这么一个一个书写肯定会累死人的,SpringBoot提供了一个对象,能够把所有的数据都封装到这一个对象中,这个对象叫做Environment
,使用自动装配注解可以将所有的yaml
数据封装到这个对象中
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private Environment environment;
@GetMapping("/getBooks")
public String getBooks() {
System.out.println("SpringBoot 正在运行~");
System.out.println("单一数据country是:" + environment.getProperty("country"));
System.out.println("对象的某个属性值是:" + environment.getProperty("user1.name"));
System.out.println("普通数组的某个值是:" + environment.getProperty("hobby[0]"));
System.out.println("对象数组的某个属性的值是:" + environment.getProperty("users[0].age"));
return "Hello,SpringBoot is running";
}
}
运行结果也是完全正确的!
注意:Environment对应的包不要导错了。是org.springframework.core.env.Environment包下的
3、读取对象数据
单一数据读取书写比较繁琐,全数据封装又封装的太厉害了,每次拿数据还要一个一个的getProperties(),总之用起来都不是很舒服。由于Java是一个面向对象的语言,很多情况下,我们会将一组数据封装成一个对象。SpringBoot也提供了可以将一组yaml对象数据封装一个Java对象的操作
首先定义一个对象,并将该对象纳入Spring管控的范围,也就是定义成一个bean,然后使用注解@ConfigurationProperties
指定该对象加载哪一组yaml中配置的信息。
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private User1 user1;
@GetMapping("/getBooks")
public String getBooks() {
System.out.println("SpringBoot 正在运行~");
System.out.println(user1);
return "Hello,SpringBoot is running";
}
}
这个@ConfigurationProperties
必须告诉他加载的数据前缀是什么,这样当前前缀下的所有属性就封装到这个对象中。记得数据属性名要与对象的变量名一一对应啊,不然没法封装。其实以后如果你要定义一组数据自己使用,就可以先写一个对象,然后定义好属性,下面到配置中根据这个格式书写即可。
运行结果依然是正确的!
4、数据引用
在书写yaml数据时,经常出现如下现象,比如很多个文件都具有相同的目录前缀
center:
dataDir: /usr/local/fire/data
tmpDir: /usr/local/fire/tmp
logDir: /usr/local/fire/log
msgDir: /usr/local/fire/msgDir
或者
center:
dataDir: D:/usr/local/fire/data
tmpDir: D:/usr/local/fire/tmp
logDir: D:/usr/local/fire/log
msgDir: D:/usr/local/fire/msgDir
这个时候就可以使用引用格式来定义数据,其实就是搞了个变量名,然后引用变量了,格式如下:
baseDir: /usr/local/fire
dataDir: ${baseDir}/data
tmpDir: ${baseDir}/tmp
logDir: ${baseDir}/log
msgDir: ${baseDir}/msgDir
注意事项:在书写字符串时,如果需要使用转义字符,需要将数据字符串使用双引号包裹起来
lesson: "Spring\tboot\nlesson"
小结
- 在配置文件中可以使用${属性名}方式引用属性值
- 如果属性中出现特殊字符,可以使用双引号包裹起来作为字符解析
八、总结
SpringBoot配置文件的使用也同样简化了开发的步骤,非常重要,我们要熟练使用。博主正在积极准备SpringBoot整合第三方技术相关的博客文章,喜欢的话,可以给博主一个赞哦~~
- 点赞
- 收藏
- 关注作者
评论(0)