Spring与Maven多环境配置
参考:
- https://www.cnblogs.com/0201zcr/p/6262762.html
1. Maven Profile
1.1背景
在开发过程中,我们的软件会面对不同的运行环境,比如开发环境、测试环境、生产环境,而我们的软件在不同的环境中,有的配置可能会不一样,比如数据源配置、日志文件配置、以及一些软件运行过程中的基本配置,那每次我们将软件部署到不同的环境时,都需要修改相应的配置文件,这样来回修改,很容易出错,而且浪费劳动力。 maven提供了一种方便的解决这种问题的方案,就是profile功能。
1.2使用maven的profiles标签定义不同的环境
请看如下代码:
<!-- 项目的pom.xml -->
<profiles>
<!-- 定义一个开发环境 -->
<profile>
<!-- 该环境唯一id -->
<id>dev</id>
<properties>
<!-- 定义了一个属性activeProfile, 其实属性名可以随便写的, 当dev环境被激活时, 可以使用${activeProfile}来应用这个属性, 他的值就是dev
<activeProfile>dev</activeProfile>
</properties>
<!-- 设置该环境默认激活 -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<activeProfile>test</activeProfile>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<activeProfile>prod</activeProfile>
</properties>
</profile>
</profiles>
在上面我们定义了三个环境分别是dev, test, prod, 其中dev环境默认激活, 并且每个环境都有一个属性activeProfile, 当dev激活时activeProfile=dev, 当test激活时activeProfile=test
其实使用activeProfile的作用就是一个标识, 标识当前是哪一个环境激活了, 我们可以应用该字段到许多地方, 及其灵活
1.3标签和标签的结合使用
在上述内容中我们使用及其子标签分别定义了不同环境中activeProfile的值, 请看如下代码中的使用:
目录结构
├── _pom.xml
├── _src
| ├──_main
| |--_java
| |--_resources
| |--application.yml
| |--application-dev.yml
| |--application-prod.yml
| |--application-test.yml
| └── test
pom.xml
<profiles>
<!-- profiles内容同1.2内容 -->
</profiles>
<build>
<resources>
<!-- 使用如下resource标签将src/main/resources中的以application-开头的yml文件排除掉 -->
<!-- 也就是说maven打包的时候是不会将application-的yml文件开头的文件打包上的-->
<resource>
<directory>src/main/resources/</directory>
<excludes>
<exclude>application-*.yml</exclude>
</excludes>
</resource>
<!-- 使用如下resource标签将src/main/resources中的application-${activeProfile}.yml文件包括上 -->
<!-- 也就是指定maven在打包的时候需要将该文件打包上 -->
<!-- 当dev环境激活的时候application-${activeProfile}.yml表示的就是application-dev.yml -->
<resource>
<directory>src/main/resources</directory>
<includes>
<include>application-${activeProfile}.yml</include>
</includes>
</resource>
</resources>
</build>
上述代码就是在dev环境激活的时候, 将src/main/resources文件中application-开头的yml文件不打包, 除了application-dev.yml
使用maven打包时通过-P参数,-P后跟上profile的唯一id,如下命令打包
mvn clean package -Pprod
在idea中:
查看项目target目录:
2. 在yml中引入maven属性
2.1 使用
pom.xml
<profiles>
<!-- 定义三个环境dev, prod, test, 其中dev环境默认激活 -->
<!-- 定义代码省略, 参考上面的定义 -->
</profiles>
<build>
<resources>
<!-- 使用如下resource标签将src/main/resources中的以application-开头的文件和application.yml排除掉 -->
<!-- 也就是说maven打包的时候是不会将application-开头的文件和application.yml打包上的-->
<resource>
<directory>src/main/resources/</directory>
<excludes>
<exclude>application.yml</exclude>
<exclude>application-*.yml</exclude>
</excludes>
</resource>
<!-- 使用如下resource标签将src/main/resources中的application.yml和application-${activeProfile}.yml文件包括上 -->
<!-- 也就是指定maven在打包的时候需要将该文件打包上 -->
<!-- 当dev环境激活的时候application-${activeProfile}.yml表示的就是application-dev.yml -->
<resource>
<directory>src/main/resources</directory>
<!-- 这个filtering非常重要, 意思是需要maven-resources-plugin将include文件中引用的maven属性进行解析 -->
<filtering>true</filtering>
<includes>
<include>application.yml</include>
<include>application-${activeProfile}.yml</include>
</includes>
</resource>
</resources>
<plugins>
<!-- 导入该插件来解析yml中引用的maven属性 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
</plugins>
</build>
上述代码使用maven-resources-plugin插件将application.yml和application-${activeProfile}.yml中引用的mavne属性进行解析, 注意一定要开启filtering
不熟悉的话可以百度 [maven filtering]和[在yml中引入maven属性] 熟悉或者获取更多使用技巧
application.yml
spring:
profiles:
# 引入我们定义的自定义变量
active: '@activeProfile@'
application:
# 引用<name>标签中的值
name: '@project.name@'
这样当我们激活dev环境的时候, maven将会打包application.yml和application-dev.yml, 并且将spring.profiles.active和spring.application.name进行解析
2.2 遇到的坑, 参考https://www.cnblogs.com/0201zcr/p/6262762.html
这段只是引用别人博客中内容, 未实际验证
在application.xml文件中不能出现@关键字,就算你注释了也不行。当出现@了,之后的所有环境变量将不会被注入
如:
3. Spring Profile多环境配置
在springboot中, 定义三个配置文件, application.yml, application-dev.yml, application-test.yml, application-prod.yml
在application.yml中配置通用的配置, application-dev.yml配置开发环境下的配置
在pom.xml中
<profiles>
<!-- 定义三个环境dev, prod, test, 其中dev环境默认激活 -->
<!-- 定义代码省略, 参考上面的定义 -->
</profiles>
<build>
<resources>
<!-- 使用如下resource标签将src/main/resources中的以application-开头的文件和application.yml排除掉 -->
<!-- 也就是说maven打包的时候是不会将application-开头的文件和application.yml打包上的-->
<resource>
<directory>src/main/resources/</directory>
<excludes>
<exclude>application.yml</exclude>
<exclude>application-*.yml</exclude>
</excludes>
</resource>
<!-- 使用如下resource标签将src/main/resources中的application.yml和application-${activeProfile}.yml文件包括上 -->
<!-- 也就是指定maven在打包的时候需要将该文件打包上 -->
<!-- 当dev环境激活的时候application-${activeProfile}.yml表示的就是application-dev.yml -->
<resource>
<directory>src/main/resources</directory>
<!-- 这个filtering非常重要, 意思是需要maven-resources-plugin将include文件中引用的maven属性进行解析 -->
<filtering>true</filtering>
<includes>
<include>application.yml</include>
<include>application-${activeProfile}.yml</include>
</includes>
</resource>
</resources>
<plugins>
<!-- 导入该插件来解析yml中引用的maven属性 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
</plugin>
</plugins>
</build>
并且在application.yml中
spring:
profiles:
active: '@activeProfile@'
这样当pom.xml中定义的dev环境激活时, active被修改成dev(详细参考第2部分), spring读取application.yml后将会读取application-dev.yml中的配置, 如果两个配置重复, 以application-dev.yml中的为准
同时, 我们还可以使用@Profile来配置不同环境下的Bean
比方说我们在dev, test环境下需要使用Swagger, 但是在prod环境下不使用Swagger
@Configuration
@Profile({"dev", "test"})
@EnableSwagger2
public class Swagger2Config {
}
@Profile将会匹配spring.profiles.active参数, 上面代码的意思是只用在dev或者test环境被激活的时候才配置Swagger2Config
@Profile可以使用的地方
- @component或@Configuration修饰的类上
- 作为元注解修饰自定义注解
- 任何@Bean修饰的方法上
@Profile取反
@Configuration
@Profile("!prod")
@EnableSwagger2
public class Swagger2Config {
}
// 上面代码意思是在非prod环境下配置Swagger2Config, 即该bean在dev和prod环境中都会生效
4. spring.profiles.include属性
在application.yml中
spring:
profiles:
include: database
意味着不管是在什么环境中, 都会去加载application-database.yml中的独有的配置, 非独有配置将不会生效