实际工作中项目会依次部署到多套环境,例如测试、灰度和生产。一般来说每套环境的资源地址都是独立的,这意味着项目在构建时要动态决定启用哪套配置以适应当前的环境。
下面介绍在maven中实现根据环境动态处理配置的两种方式。
方式一
1.在项目POM文件中配置profile
在构建项目时添加-P [profile_ID]
选项可以激活指定profile,可以写多个ID,中间用逗号分隔即可。如果不指定具体的profile则默认启用local,因为在local里面配置了activeByDefault=true。
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
| <profiles> <profile> <id>local</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <package.environment>default,local</package.environment> </properties> </profile> <profile> <id>dev</id> <properties> <package.environment>default,dev</package.environment> </properties> </profile> <profile> <id>test</id> <properties> <package.environment>default,test</package.environment> </properties> </profile> <profile> <id>staging</id> <properties> <package.environment>default,staging</package.environment> </properties> </profile> <profile> <id>production</id> <properties> <package.environment>default,production</package.environment> </properties> </profile> </profiles>
|
可以看到上面配置了几个profile,分别表示各个环境的变量。其中id表示对应的环境标识,properties配置环境值(可以N个),里面的属性是自定义的。
2.在spring配置文件application.yml中配置
这里假设你在用springmvc,该框架有一个配置文件启用参数(spring.profiles.active),在编译时maven能够将里面的变量(@package.environment@)替换成具体的值(由编译时-P选项指定的profile配置),以此达到切换配置的目的。
1 2 3 4 5
| spring: application: name: test profiles: active: @package.environment@
|
3.maven编译时激活相应的profile
mvn clean install package -P dev
激动ID为dev的配置属性,同时替换掉spring的配置文件application.yml中的spring.profiles.active属性,按照前面的配置值应该为defualt,dev
。
mvn clean install package -P production
激活ID为production的profile。
注意:本方法利用了spring的active功能,这意味着你应该准备如下配置文件:
1 2 3 4 5 6 7
| resources ├── application-dev.yml ├── application-local.yml ├── application-production.yml ├── application-staging.yml ├── application-test.yml ├── application.yml
|
例如:在主文件application.yml中配置了active为defualt,dev,那么spring会加载两个配置文件,分别是application.yml和application-dev.yml,如果两份文件中有相同属性,则后者覆盖前者。
4.如果没有使用spring框架
解决的思路是相同的,都是利用maven激活配置属性的功能,程序在读取配置时根据激活的属性进行判断就可以了。
方式二
跟方式一相比,方式二不依赖于spring,它的原理是把指定的配置文件内容复制到项目配置中。
假设,你在项目src/main/resources
目录下有三个文件:
environment.properties
默认配置,也是项目中唯一能读取到的配置。
environment.test.properties
测试环境配置,项目中读取不到。
environment.prod.properties
生产环境配置,项目中读取不到。
1.在项目POM文件中配置profile
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
| <profiles>
<profile> <id>test</id> <build> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <phase>test</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <delete file="${project.build.outputDirectory}/environment.properties"/> <copy file="src/main/resources/environment.test.properties" tofile="${project.build.outputDirectory}/environment.properties"/> </tasks> </configuration> </execution> </executions> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skip>true</skip> </configuration> </plugin> </plugins> </build> </profile>
.. Other profiles go here ..
</profiles>
|
2.maven编译时激活test profile
在命令行执行mvn -P test install
,它将antrun插件配置为在测试阶段执行运行目标,并将environment.test.properties文件复制到environment.properties。
小结
在中大型项目中通常会采用集中配置管理系统,它除了能让应用根据不同环境读取对应的配置文件,还可以支持在系统上动态更改配置并立即生效,如此就不用改一次配置文件就得繁琐的发布一遍了。