SpringBoot多环境配置与配置文件拆分

image

多环境配置

我们知道 springboot 是支持多环境配置的,具体做法就是将 application.properties 按照不同环境命名,例如我们需要区分两个环境,开发环境(dev) 和 正式环境(rc),那我们就可以使用如下配置:

1
2
3
4
5
- src/main/java
- src/main/resources
- application.properties # 基础公共配置,如应用端口,应用名称
- application-dev.properties # 开发环境配置,如开发环境数据库信息
- application-rc.properties # 正式环境配置,如正式环境数据库信息

只要将这三份配置文件放在 resources 文件夹中,通过打包后的启动命令 java -jar xx.jar --spring.profiles.active=rc 就可以让应用使用 application-rc.properties 中的配置。

自定义配置文件

一般情况下,我们可以将所有的配置都放在 application.properties 中,但如果 application.properties 中的配置项过多,那么我们也可以进行拆分,将一些配置信息独立出来放在一个新的配置文件中,如:

1
2
3
4
- src/main/java
- src/main/resources
- application.properties
- cdn.properties # CDN配置

默认情况下,springboot 是不会加载 cdn.properties,在这种情况下,我们需要手动加载这份配置文件,以使用注解@PropertySource 为例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration
@PropertySource(value = {"classpath:cdn.properties"})
public class CdnProperty {

@Value("${privite.key}")
private String privateKey;

@Value("${public.key}")
private String publicKey;

public String getPrivateKey() {
return privateKey;
}

public String getPublicKey() {
return publicKey;
}

}

自定义配置文件的多环境配置

如果我们的自定义配置文件也要按照不同环境区分,又改如何处理呢?如:

1
2
3
4
5
6
7
8
- src/main/java
- src/main/resources
- application.properties
- application-dev.properties
- application-rc.properties

- cdn-dev.properties # 开发环境CDN配置
- cdn-rc.properties # 正式环境CDN配置

Maven 配置

我们可以使用maven 中的 profile 配置,该配置可以在打包的时候只打包指定 profile下的配置。比如,我们可以把配置文件调整下结构:

1
2
3
4
5
6
7
8
9
10
11
12
- src/main/java
- src/main/resources
- common # 基础配置文件夹
- application.properties
- application-dev.properties
- application-rc.properties

- dev # 开发环境配置文件夹
- cdn.properties # 开发环境CDN配置

- rc # 正式环境配置文件夹
- cdn.properties # 正式环境CDN配置

同时在 pom.xml 中添加 <profiles></profiles> 配置,如:

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
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!-- 省略其他配置 -->

<profiles>
<profile>
<id>local</id> <!-- profile名称为local -->
<activation>
<activeByDefault>true</activeByDefault> <!-- 默认激活 -->
</activation>
<build>
<resources>
<resource>
<directory>src/main/resources/local</directory> <!-- profile对应的文件夹 -->
</resource>
</resources>
</build>
</profile>
<profile>
<id>dev</id> <!-- profile名称为dev -->
<build>
<resources>
<resource>
<directory>src/main/resources/dev</directory> <!-- profile对应的文件夹 -->
</resource>
</resources>
</build>
</profile>
</profiles>

<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/resources/common</directory> <!-- 基础配置文件夹 -->
<filtering>true</filtering>
</resource>
</resources>

<!-- 省略其他配置 -->

</build>
</project>

修改完成后,我们可以使用 maven 打包命令-P 来打包指定的 profile (如 mvn clean package -Pdev 打包 dev的文件夹下的配置文件),这种情况下,我们不需要修改上面 CdnProperty类,因为此时的 classpath中的 cdn.properties 就是 dev文件夹的配置文件。

因为此处我们没有分开打包 application.properties,所以 **启动命令依然要指定 --spring.profiles.active**。

Spring 配置

1
2
3
4
5
6
7
8
- src/main/java
- src/main/resources
- application.properties
- application-dev.properties
- application-rc.properties

- cdn-dev.properties # 开发环境CDN配置
- cdn-rc.properties # 正式环境CDN配置

在之前 Spring中Properties 中,介绍过 @PropertySources 的部分源码,其中有一段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// ConfigurationClassParser.java
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
// .....
for (String location : locations) {
try {
// 路径支持占位符替换
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
Resource resource = this.resourceLoader.getResource(resolvedLocation);
ResourcePropertySource rps = (StringUtils.hasText(name) ?
new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource));
// 将资源文件添加到`environment`中
addPropertySource(rps);
}
// ....
}
}

可以看到,其实 @PropertySource(value = {"classpath:cdn.properties"}) 是支持 profile 的占位符替换的,因此我们只要修改下路径即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration
@PropertySource(value = {"classpath:cdn-${spring.profiles.active}.properties"}) // 使用 ${spring.profiles.active} 做占位符替换
public class CdnProperty {

@Value("${privite.key}")
private String privateKey;

@Value("${public.key}")
private String publicKey;

public String getPrivateKey() {
return privateKey;
}

public String getPublicKey() {
return publicKey;
}

}