实际开发中一个项目至少对应开发、测试、生成三种环境,如何方便的管理多环境是今天的要讨论的主题
Spring Profile 是 Spring 提供的多环境管理方案。
如图,每种环境都对应一个 properties
文件,然后在 application.properties
中配置一下要使用的环境
spring.profiles.active=dev 复制代码
上面配置匹配的是 application-dev.properties
,如果写的是test,则匹配 application-test.properties
。也就是说, Spring Profile 对配置文件的命名有要求,必须是 application-
开头
除了配置环境外,一些不随环境而变化的配置也应该放到 application.properties
中, application-.properties
最好只存放与环境相关的配置项
以上就是 Spring Profile 给出的多环境管理方案。通过改变 spring.profiles.active
的值来切换不同的环境。这种方法简单易懂,但有两个问题。
spring.profiles.active
为了解决这两个问题,我们需要 maven profile 的配合
maven 的 profile 可以让我们定义多套配置信息,并指定其激活条件,然后在不同的环境下使用不同的profile配置。
在maven中有两个地方可以配置 profile
pom.xml {user}/.m2/settings.xml
settings.xml
中的 profile 不同的地方 profile 中能定义的信息也不相同
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd"> ... <profiles> <profile> <id>...</id> <activation>...</activation> <repositories>...</repositories> </profile> </profiles> ... </settings> 复制代码
由于能配置的东西有限,一般都会将 maven profile 配置在 pom.xml
pom.xml
中 的profile pom.xml
中:profile 能定义的东西就非常多了,如下
<profiles> <profile> <id>..</id> <activation>...</activation> <build>...</build> <modules>...</modules> <repositories>...</repositories> <pluginRepositories>...</pluginRepositories> <dependencies>...</dependencies> <reporting>...</reporting> <dependencyManagement>...</dependencyManagement> <distributionManagement>...</distributionManagement> </profile> </profiles> 复制代码
当然我们的目的也不是把它配全,而是解决 Spring Profile 遗留下来的两个问题。
首先看第一个问题
"每次切换环境要手动垓下 spring.profiles.active
的值"
这个问题就可以通过配置 profile 解决,在pom的根节点下添加
<profiles> <profile> <id>dev</id> <activation> <!-- activeByDefault 为 true 表示,默认激活 id为dev 的profile--> <activeByDefault>true</activeByDefault> </activation> <!-- properties 里面可以添加自定义节点,如下添加了一个env节点 --> <properties> <!-- 这个节点的值可以在maven的其他地方引用,可以简单理解为定义了一个叫env的变量 --> <env>dev</env> </properties> </profile> <profile> <id>test</id> <properties> <env>test</env> </properties> </profile> <profile> <id>prod</id> <properties> <env>prod</env> </properties> </profile> </profiles> 复制代码
如上,定义了三套环境,其中id为dev的是默认环境,三套环境中定义了叫 env的“变量”
如果你用的是idea编辑器,添加好后,maven控件窗口应该会多出一个 Profiles,其中默认值就是上面配置的dev
最小化的 profiles 已经配置好了,通过勾选上图中的Profiles,就可以快速切换 maven的 profile 环境。
现在 maven profile 可以通过 勾选上图中的Profiles 快速切换环境
Spring Profile 还得通过 手动修改 spring.profiles.active
的值来切环境
现在的问题是怎样让 maven profile的环境与Spring Profile一一对应,达到切换maven profile环境时,Spring Profile环境也被切换了
还记得maven profile 中定义的 env "变量"吗,现在只需要把
spring.profiles.active=dev 复制代码
改成
spring.profiles.active=@env@ 复制代码
就将maven profile 与 Spring Profile 环境关联起来了
当maven profile 将 环境切换成 test 时,在pom中定义的id为test的profile环境将被激活,在该环境下env的值是test,maven插件会将 @env@ 替换为 test,这样Spring Profile的环境也随之发生了改变。从上面可以看出,自定义的"变量"env的值还不能乱写,要与Spring Profile的环境相对应。
pom
文件中配置 profiles application.properties
配置文件中添加 spring.profiles.active=@env@
打包的时候,要手动删除其他环境的配置文件,不然其他环境的敏感信息就都打包进去了
解决这个问题需要在pom根节点下中配置 build 信息
<build> <resources> <resource> <directory>src/main/resources</directory> <excludes> <!--先排除application开头的配置文件--> <exclude>application*.yml</exclude> </excludes> </resource> <resource> <directory>src/main/resources</directory> <!--filtering 需要设置为 true,这样在include的时候,才会把 配置文件中的@env@ 这个maven`变量`替换成当前环境的对应值 --> <filtering>true</filtering> <includes> <!--引入所需环境的配置文件--> <include>application.yml</include> <include>application-${env}.yml</include> </includes> </resource> </resources> <!--<plugins>--> <!-- <plugin>--> <!-- <groupId>org.springframework.boot</groupId>--> <!-- <artifactId>spring-boot-maven-plugin</artifactId>--> <!-- </plugin>--> <!--</plugins>--> </build> 复制代码
如上,配置了两个 <resource>
,第一个先排除了src/main/resources目录下所有 application 开头是配置文件,第二个在第一个的基础上添加了所需的配置文件。注意 application-${env}.yml
,它是一个动态变化的值,随着当前环境的改变而改变,假如当前环境是 id叫 dev的 profile,那么env的值为 dev。
这样配置后,maven在build时,就会根据配置先排除掉指定的配置文件,然后根据当前环境添加所需要的配置文件。