springboot采纳了建立生产就绪spring应用程序的观点。 Spring Boot**约定优于配置**的惯例,旨在让您尽快启动和运行。
在一般情况下,我们不需要做太多的配置就能够让Spring Boot程序正常运行。在一些特殊的情况下,我们需要做修改一些配置,或者需要有自己的配置属性。
当我们创建一个springboot项目的时候,系统默认会为我们在src/main/Java/resources目录下创建一个application.properties。这个文件就是默认项目默认的配置文件。
当你双击打开这个application.properties配置文件,你会惊讶地发现,配置文件里面是空空如也。可是当你运行的时候,你发现程序能够正常运行,并且端口已经绑定了8080,并向外提供了服务。这就体现了**约定优于配置**的原则,也就是说你如果不配置那么我默认就用8080端口作为服务端口,如果你想改变这个端口号,那么你就可以在配置中设置一下。
刚才已经说了,默认IDEA使用了application.properties格式的配置文件,而现在很多开发者喜欢使用application.yml格式的配置文件。从我本人的喜好来说,我喜欢application.properties格式的配置文件,虽然有些冗余,但是简单直接,不容易出错。那么两种格式的配置文件,有什么不同呢?下面咱们来详细地研究一下。
当我们构建完Spring Boot项目后,会在resources目录下给我们一个默认的全局配置文件 application.properties,这是一个空文件,因为Spring Boot在底层已经把配置都给我们自动配置好了,当在配置文件进行配置时,会修改SpringBoot自动配置的默认值。
application.properties配置文件的名字是固定的,它的位置也是固定。如果你修改了配置文件的名字或者移动了位置,SpringBoot项目则找不到这个配置文件,会使用默认的配置。
application.properties 配置文件比较简单,形式如下
# 等号的两边没有空格
key1=value
# 等号的两边有空格
key1 = value
等号两边有没有空格,通过实验证明是没有区别的。我个人是习惯于没有空格的写法。
上面的配置文件中,value到底是数字呢?还是字符串呢?新学者可能会有这个疑惑,实际上他是字符还是数字,主要看在实际使用中怎么去用。比如下面配置,一般SpringBoot工程都要这样设置:
# 自定义服务器的端口号
server.port=9090
# 自定义微服务的名字
spring.application.name=demo-new
# 自定义属性
site.name="hello"
从上面的配置文件,可以看出来等号右边的值可以使数字,也可以是字符串。
上面的配置中,有的人可能有了疑问,如果右边的值是字符串,需不需要加个双引号呢?如果加了是什么效果呢?
答案就是不需要加入双引号。一旦加了双引号,SpringBoot会把双引号也当做字符串的组成部分。
对于配置文件中值的读取,可以参考下面的代码:
@Value("${server.port}")
private Integer serverPort;
@Value("${spring.application.name}")
private String serverName;
@Value("${site.name}")
private String siteName;
有的时候,配置文件中可能需要引入一些键值对的值,这些和上面的值写法就有点不一样了。具体写法如下:
server.maps={name:'dev-server',ip:'192.168.1.100',port:'9999'}
而对于map的读取,可以参考下面代码:
@Value("#{${server.maps}}")
private Map<String,String> serverMaps;
数组
# 数组类型
site.names=david,lisa,alex,lucy
通过代码读取:
@Value("${site.names}")
private String[] siteNames;
List
# List类型
site.whites=1,2,3,4
通过代码读取:
@Value("${site.whites}")
private List siteWhites;
Set
# Set类型
site.ages=66,99,88,34
通过代码读取:
@Value("${site.ages}")
private Set siteAges;
Spring Boot配置文件支持占位符,一些用法如下
- 随机数
${random.value}
${random.int}
${random.long}
${random.int(10)}
${random.int[1024,65536]}
默认值
占位符获取之前配置的值,如果没有可以是用:指定默认值
person.last-name=张三${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
person.dog.age=15
示例代码
配置如下:
# 占位符
site.age=${random.int[1024,65536]}
site.uuid=张三${random.uuid}
代码如下:
@Value("${site.age}")
private Integer siteAge;
@Value("${site.uuid}")
private String siteUuid;
.yml文件,通过:来分层,结构上,有比较明显的层次感,最后key赋值的:不要留空格,视频中已经了教训,如果你的不行,你再尝试加一个空格,然后再试试。但是赋值冒号(:)的后面一般是需要空格的。而且yml文件的空格对齐要求还是比较严格的,需要认真对待,否则出了错误不容易排查。
yml格式除了书写格式,在使用中是一样的。可以参考下面的示例:
server:
port: 9090
servlet:
session:
timeout: 120m
spring:
application:
name: demo-new
## 自定义属性
# 数字和字符型
site:
name: hello
# map类型
maps: {name:'dev-server',ip:'192.168.1.100',port:'9999'}
# List类型
whites:
- 1
- 2
- 3
- 4
# 数组类型
names:
- david
- lisa
- alex
- lucy
# Set类型
ages:
- 66
- 99
- 88
- 34
# 占位符
age: ${random.int[1024,65536]}
uuid: 张三${random.uuid}
通过代码来读取如下:
@Value("${server.port}")
private Integer serverPort;
@Value("${spring.application.name}")
private String serverName;
@Value("${site.name}")
private String siteName;
@Value("#{${site.maps}}")
private Map<String,String> siteMaps;
@Value("${site.whites}")
private List siteWhites;
@Value("${site.names}")
private String[] siteNames;
@Value("${site.ages}")
private Set siteAges;
@Value("${site.age}")
private Integer siteAge;
@Value("${site.uuid}")
private String siteUuid;
server.port=9090
spring.application.name=demo-new
server.servlet.session.timeout=120m
## 自定义属性
# 数字和字符型
site.name="hello"
# map类型
site.maps={name:'dev-server',ip:'192.168.1.100',port:'9999'}
# List类型
site.whites=1,2,3,4
# 数组类型
site.names=david,lisa,alex,lucy
# Set类型
site.ages=66,99,88,34
# 占位符
site.age=${random.int[1024,65536]}
site.uuid=张三${random.uuid}
server:
port: 9090
servlet:
session:
timeout: 120m
spring:
application:
name: demo-new
## 自定义属性
# 数字和字符型
site:
name: hello
# map类型
maps: {name:'dev-server',ip:'192.168.1.100',port:'9999'}
# List类型
whites:
- 1
- 2
- 3
- 4
# 数组类型
names:
- david
- lisa
- alex
- lucy
# Set类型
ages:
- 66
- 99
- 88
- 34
# 占位符
age: ${random.int[1024,65536]}
uuid: 张三${random.uuid}
package com.shenmazong.demonew;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.*;
@SpringBootTest
class DemoNewApplicationTests {
@Value("${server.port}")
private Integer serverPort;
@Value("${spring.application.name}")
private String serverName;
@Value("${site.name}")
private String siteName;
@Value("#{${site.maps}}")
private Map<String,String> siteMaps;
@Value("${site.whites}")
private List siteWhites;
@Value("${site.names}")
private String[] siteNames;
@Value("${site.ages}")
private Set siteAges;
@Value("${site.age}")
private Integer siteAge;
@Value("${site.uuid}")
private String siteUuid;
@Test
void contextLoads() {
System.out.println("serverPort="+serverPort);
System.out.println("serverName="+serverName);
System.out.println("siteName="+siteName);
System.out.println("serverMaps="+siteMaps);
System.out.println("siteWhites="+siteWhites);
System.out.println("siteNames="+siteNames);
System.out.println("siteAges="+siteAges);
System.out.println("siteAge="+siteAge);
System.out.println("siteUuid="+siteUuid);
}
}
如果工程中同时存在application.properties文件和 application.yml文件,yml文件会先加载,而后加载的properties文件会覆盖yml文件。所以建议工程中,只使用其中一种类型的文件即可。
上面的描述,有些模棱两可,到底是谁起作用呢?
通过实验,我们发现,最终起作用的是application.properties文件,而application.yml并没有起作用。
使用springboot开发项目时有时候需要引入外部的配置文件,如果里面值包含中文则会产生乱码。
一般会在IDEA中进行文件编码的设置:
先修改properties文件的编码格式
修改为utf-8,同时去Idea里面修改properties编码设置:
Settings ——》Editor ——》 File Encodings
选择UTF-8,同时勾选Transparent native-to-ascii conversion,如下图
如果使用配置类,则只需在注解中添加编码设置即可。
在引入properties文件的注解上指定encoding格式。
@Component
@ConfigurationProperties(prefix = "userInfo")
@PropertySource(value = {"classpath:user.properties"}, encoding = "utf-8")
添加 encoding = “utf-8”
这样就可解决乱码问题。