spring boot的配置文件
配置文件的作用:就是用来修改spring boot配置的默认值。
配置文件的形式和格式
springboot使用一个全局的配置文件(名字是固定的),有如下两种形式:
- application.properties
- application.yml
- 注意 “k: v” 之间必须要有空格,并且以空格的缩进控制层级关系,空格多少无所谓,只要左对齐的一列配置都属于同一层级
- 值的写法:
- 字面值:普通的值(数字,字符串,布尔值),注意字符串默认不加引号,如果加了引号,那么单引号和双引号的作用不同,双引号不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思(例如 name: “zhangsan\nlisi” 输出 zhangsan换行lisi),单引号会转义特殊字符,特殊字符最终只是一个普通的字符串数据(例如 name: “zhangsan\nlisi”,输出 zhangsan\nlisi);
- 对象和map:有两种写法,第一种是使用多行缩进的方式,第二种是行内写法(例如 student: {name: zhangsan,age: 18});
- 数组和set:也有两种写法,第一种是使用多行 “- 值” 表示数组中的一个个元素;第二种是行内写法(例如 pets: [cat, dog, pig])
application.properties 文件格式
1 2
| server.port: 8080 server.path: /zdemo-springboot-hello
|
application.yml 文件格式
1 2 3
| server: port: 8080 path: /zdemo-springboot-hello
|
配置文件自定义键值
1 2 3 4 5 6
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| server: port: 8081
person: lastName: zhangsan age: 18 boss: false birth: 2019/01/01 map: {k1: v1, k2: v2} list: - lisi - wangwu dog: name: xiaohei age: 2
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| package com.keyllo.demo.bean;
@Component @ConfigurationProperties(prefix = "person")
public class Person { private String lastName; private Integer age; private Boolean boss; private Date birth;
private Map<String,Object> map; private List<Object> list; private Dog dog;
@Override public String toString() { return "Person{" + "lastName='" + lastName + '\'' + ", age=" + age + ", boss=" + boss + ", birth=" + birth + ", map=" + map + ", list=" + list + ", dog=" + dog + '}'; } }
@Component public class Person2 { @Value("${person.last-name}") private String lastName; @Value("#{11*2}") private Integer age; @Value("true") private Boolean boss;
@Override public String toString() { return "Person2{" + "lastName='" + lastName + '\'' + ", age=" + age + ", boss=" + boss + '}'; } }
|
测试单元
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| import com.demo.App; import com.demo.model.Person; import com.demo.model.Person2; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = App.class) public class DemoTest01 {
@Autowired private Person person; @Autowired private Person2 person2;
@Test public void test01() { System.out.println(person); System.out.println(person2); } }
|
@ConfigurationProperties 和 @Value 的区别
|
@ConfigurationProperties |
@Value |
| 功能 |
批量注入配置文件中的属性 |
一个个绑定配置文件中的属性 |
| 松散语法(键xx-yy等价于 xxYy) |
支持 |
不支持 |
| SpEl |
不支持 |
支持 |
| JSR303数据校验 |
支持 |
不支持 |
- 配置文件是yml或properties他们都能够获取到值
- 如果说只是在某个业务逻辑中需要获取一下配置文件中的某项值,采用 @Value
@PropertySource
使用@PropertySource 加载指定配置文件:注意目前 @PropertySource 目前不支持 yml文件,所以如果使用@PropertySource加载指定配置文件,那么只能使用 properties文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Component @ConfigurationProperties(prefix = "person") @PropertySource(value = {"classpath:person.properties"}) public class Person { private String lastName; private Integer age; private Boolean boss; private Date birth;
private Map<String,Object> map; private List<Object> list; private Dog dog;
}
|
resources/person.properties
1 2 3 4 5 6 7 8 9 10 11 12
| person.last-name=zhang\nsan person.department=yan\\nfa\\nbu person.age=23 person.birhtday=2019/01/01 12:12:12 person.boss=true person.map.k1=v1 person.map.k2=v2 person.list[0]=0 person.list[1]=1 person.list[2]=2 person.dog.name=xiaohei person.dog.age=${random.int[10,20]}
|
@ImportResource
使用@ImportResource导入spring原始的xml配置文件
方式一(xml方式):
1 2 3 4 5 6 7
| @ImportResource(locations = {"classpath:beans.xml"}) @SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
|
1 2 3 4 5 6
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="helloService" class="com.keyllo.demo.service.HelloService"></bean> </beans>
|
1 2 3 4 5 6 7 8 9 10 11 12
| @SpringBootTest(classes = App.class) public class DemoTest02 {
@Autowired private ApplicationContext ioc;
@Test public void helloService() { boolean b = ioc.containsBean("helloService"); System.out.println(b); } }
|
方式二(使用spring boot推荐的全注解代替xml的方式):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| package com.keyllo.demo.config; import com.keyllo.demo.service.HelloService; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class MyAppConfig {
@Bean public HelloService helloService() { System.out.println("给容器中添加helloService组件!"); return new HelloService(); } }
|
配置文件中的占位符
1) 随机数
${random.value}、${random.int}、${random.long}、${ramdom.int(10)}、${random.int[1024,65536]}
2) 占位符获取之前配置的值,如果没有可以使用“:”指定默认值
1 2 3 4 5 6 7 8 9
| person.last-name=张三${random.uuid} person.age=${random.int} person.birth=2019/01/01 person.boss=false person.map.k1=v1 person.map.k2=v2 person.list=a,b,c person.dog.name=${person.hello:hello}_dog person.dog.age=15
|
profile环境
可配置不同环境的多个profile文件
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml,默认使用的是application.properties 中的配置。
激活指定的profile
yml支持多文档块方式
application.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| spring: profiles: active: test server: port: 8080
--- spring: profiles: dev server: port: 8081
--- spring: profiles: test server: port: 8082
|
配置文件的加载位置
核心配置文件的加载
spring boot 启动会扫描如下位置的 application.properties 或者 application.yml 文件作为 springboot 的默认配置文件。
-project-root-path: ./config/ 根目录下的 config 子目录,生效优先级最高
-project-root-path: ./ 项目根目录优先级次之
-classpath: ./config/ 类路径下的 config 包,再次之
-classpath: ./ 类路径根目录,即 src/main/resources,扫描优先级最低

- 优先级从上到下依次降低,高优先级的配置会覆盖低优先级的配置;注意打包的时候只会打包类路径下的文件。
- SpringBoot会从这四个位置全部加载主配置文件,形成 互补配置;
我们还可以通过 spring.config.location 来改变默认配置文件的位置。具体的做法是在项目打包好之后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置,指定的配置文件和默认加载的这些配置文件共同起作用形成互补配置。
1
| $ java -jar zdemo-springboot01.jar --spring.config.location=~/Desktop/application.properties
|
为什么遵从这样的设计呢?因为:
- 外部优先于内部:Spring Boot 的设计理念是允许运维人员在不重新拆解 Jar 包的情况下修改配置。因此,放在磁盘上(项目根目录)的文件优先级永远高于打包在 Jar 里的(classpath)文件。
- 特定目录优先于根目录:专门的 “config/“ 文件夹被视为 “更有意图” 的配置存放地。将配置文件收纳在子目录中,比直接散落在根目录下具有更高的权重。
外部配置文件和参数的加载
spring boot 以下位置加载配置;优先级从高到低;高优先级会覆盖低优先级的配置;所有配置会形成互补配置。
命令行参数(多个配置用空格分开;–配置项=值)
1 2
| $ java -jar xxx.jar --server.port=8087 --server.servlet.context-path=/abc
|
来自 java:comp/env的 JNDI属性
Java系统属性,例如 System.getProperty(“xxx”)
操作系统环境变量,例如 SERVER_PORT=8081
RandomValuePropertySource 配置的 “random.*” 属性值
jar 包外的特定 Profile 配置文件,例如 application-{profile}.properties/yml(带 spring.profiles=xxx)
Jar 包内的特定 Profile 配置文件,例如 application-{profile}.properties/yml(带 spring.profiles=xxx)
Jar 包外的主配置文件,例如 application.properties/yml(不带spring.profiles=xxx)
Jar 包内的主配置文件,例如 application.properties/yml(不带spring.profiles=xxx)
@Configuration 注解类上的 @PropertySource
通过 SpringApplication.setDefaultProperties 指定的默认属性
标题:
Spring Boot 配置文件和配置项各种问题详解