在实际开发中,我们会遇到关于配置文件的读取,获取配置文件的自定义配置,以及如何多环境下的配置文件信息的获取。
配置读取优先级
命令行参数。
从
java:comp/env得到的 JNDI 属性。通过
System.getProperties()获取的 Java 系统参数。操作系统环境变量。
RandomValuePropertySource配置的random.*属性值。如 ${random.int}、${random.long}、${random.value}、${random.uuid} 等。JAR 包外部的
application-{profile}.properties或application.yml(带 spring.profile)配置文件。JAR 包内部的
application-{profile}.properties或application.yml(带 spring.profile)配置文件。JAR 包外部的
application.properties或application.yml(不带 spring.profile)配置文件。JAR 包内部的
application.properties或application.yml(不带 spring.profile)配置文件。
(从 JAR 包外向 JAR 包内进行寻找,优先加载带{profile}的文件,再加载不带{profile}的文件)@Configuration注解类上的@PropertySource。通过
SpringApplication.setDefaultProperties指定默认属性。
注意:application.properties 文件的优先级高于 application.yml 文件的优先级。
配置依赖项
在 pom.xml 文件中,加入 spring-boot-configuration-processor 依赖项,用于读取配置值。
1 | <dependency> |
2 | <groupId>org.springframework.boot</groupId> |
3 | <artifactId>spring-boot-configuration-processor</artifactId> |
4 | <optional>true</optional> |
5 | </dependency> |
属性配置与实体类的映射
- application.properties
1 | # 32 位随机字符串 |
2 | = ${random.value} |
3 | # 随机的 int 类型数字 |
4 | = ${random.int} |
5 | # 随机的 long 类型数字 |
6 | = ${random.long} |
7 | # 100 以内的随机int类型 |
8 | = ${random.int(100)} |
9 | # 0-100 范围内的随机int类型 |
10 | = ${random.int[0,100]} |
- author.properties
1 | = yifanzheng |
2 | = star |
3 | = good boy! |
方式一
在 @Configuration 注解的类上加上 @ConfigurationProperties(prefix="前缀名") 注解,可以使用 @PropertySource 注解指定加载的配置文件,不加时默认加载 application.properties 文件
1 | /** |
2 | * AuthorConfig |
3 | * |
4 | * @author star |
5 | **/ |
6 | |
7 | (prefix = "author") |
8 | (value = "classpath:author.properties") // 指定配置文件的位置 |
9 | public class AuthorConfig { |
10 | |
11 | private String name; |
12 | |
13 | private String nickname; |
14 | |
15 | private String intro; |
16 | |
17 | public String getName() { |
18 | return name; |
19 | } |
20 | |
21 | public void setName(String name) { |
22 | this.name = name; |
23 | } |
24 | |
25 | public String getNickname() { |
26 | return nickname; |
27 | } |
28 | |
29 | public void setNickname(String nickname) { |
30 | this.nickname = nickname; |
31 | } |
32 | } |
注意:使用这种方式配置的类,在使用 @Autowired 注入时,不能直接 return 注入的对象,它只是指向 Spring 容器中对象资源的一个标识,可以通过这个标识返回该对象中的值。
方式二
使用 @Value 注解,直接映射实体类的各个属性。
1 | /* |
2 | * RandomConfig |
3 | * |
4 | * @author star |
5 | **/ |
6 | |
7 | public class RandomConfig { |
8 | |
9 | ("${rand.stringValue}") |
10 | private String stringValue; |
11 | |
12 | ("${rand.intNumber}") |
13 | private Integer intNumber; |
14 | |
15 | ("${rand.longNumber}") |
16 | private Long longNumber; |
17 | |
18 | ("${rand.number}") |
19 | private Integer number; |
20 | |
21 | ("${rand.rangeNumber}") |
22 | private Integer rangeNumber; |
23 | |
24 | public String getStringValue() { |
25 | return stringValue; |
26 | } |
27 | |
28 | public void setStringValue(String stringValue) { |
29 | this.stringValue = stringValue; |
30 | } |
31 | |
32 | public Integer getIntNumber() { |
33 | return intNumber; |
34 | } |
35 | |
36 | public void setIntNumber(Integer intNumber) { |
37 | this.intNumber = intNumber; |
38 | } |
39 | |
40 | public Long getLongNumber() { |
41 | return longNumber; |
42 | } |
43 | |
44 | public void setLongNumber(Long longNumber) { |
45 | this.longNumber = longNumber; |
46 | } |
47 | |
48 | public Integer getNumber() { |
49 | return number; |
50 | } |
51 | |
52 | public void setNumber(Integer number) { |
53 | this.number = number; |
54 | } |
55 | |
56 | public Integer getRangeNumber() { |
57 | return rangeNumber; |
58 | } |
59 | |
60 | public void setRangeNumber(Integer rangeNumber) { |
61 | this.rangeNumber = rangeNumber; |
62 | } |
63 | } |
方式三
在方法上使用 @Bean 注解,配合以上注解使用。
1 | /** |
2 | * AuthorBeanConfig 使用 @Bean 注解的方式获取配置信息 |
3 | * |
4 | * @author star |
5 | **/ |
6 | |
7 | (value = "classpath:author.properties") |
8 | public class AuthorBeanConfig { |
9 | |
10 | |
11 | (prefix = "author") |
12 | public AuthorBean getAuthorBean(){ |
13 | return new AuthorBean(); |
14 | } |
15 | } |
在没有使用 @PropertySource 注解指定加载的文件时,默认使用 application.properties 文件中与实体对象的属性相同的配置项。@PropertySources 注解优先级比较低,即使指定了加载的文件,但出现与 application.properties 文件相同的配置项时会被其覆盖。
自定义 YAML 资源文件属性配置
- 创建
user.yml文件,进行属性配置
1 | # 配置 user 对象的值 |
2 | demo: |
3 | user: |
4 | name: star |
5 | age: 22 |
6 | desc: good boy! |
- 使用注解标记
User.java对象文件
1 | /** |
2 | * UserConfig |
3 | * |
4 | * @author star |
5 | **/ |
6 | |
7 | (prefix = "demo.user") // 前缀名注释必须有,不然会报错 |
8 | (value = "classpath:user.yml",encoding = "utf-8") |
9 | public class User { |
10 | // @Value() 注解必须要 |
11 | ("${name}") |
12 | private String name; |
13 | |
14 | ("${age}") |
15 | private int age; |
16 | |
17 | ("${desc}") |
18 | private String desc; |
19 | |
20 | public String getName() { |
21 | return name; |
22 | } |
23 | |
24 | public void setName(String name) { |
25 | this.name = name; |
26 | } |
27 | |
28 | public int getAge() { |
29 | return age; |
30 | } |
31 | |
32 | public void setAge(int age) { |
33 | this.age = age; |
34 | } |
35 | |
36 | public String getDesc() { |
37 | return desc; |
38 | } |
39 | |
40 | public void setDesc(String desc) { |
41 | this.desc = desc; |
42 | } |
43 | } |
多环境配置
application-dev.properties: 开发环境application-prod.properties: 生产环境
Spring Boot 通过 application.roperties 文件,设置 spring.profiles.active 属性加载相应的文件,如:spring.profiles.active=dev。
注意:Spring Boot 根据环境激活配置文件的规则是,默认加载 application.properties 文件,当此文件配置了 spring.profiles.active=xxx 后,会加载 application-xxx.properties 文件中的配置项,并覆盖 application.properties 中相同的配置项。
最后
- 使用 YAML 文件时,属性值和冒号中间必须要有空格。
- YAML 文件在配置中文值时,读取不会出现乱码问题;properties 文件配置中文值,读取会出现乱码。因为 Spring Boot 是以
iso-8859-1的编码格式读取 properties 文件。