使用的場景
常常遇到一些專案中多環境切換的問題。比如在開發過程中用到開發環境,在測試中使用測試環境,在生產中用生產環境的情況。springboot中提供了 spring.profile.active的方式來實現多環境的切換,通過設定環境變數和啟動引數的方式。但是這樣做終究不能一勞永逸,要麼需要修改yml檔案,要麼需要記得啟動的時候帶上引數。而利用maven的profiles,可以減少很多工作。讓我們通過幾個例子一步步的掌握使用maven的profiles屬性。
快速上手
pom.xml檔案設定
<profiles>
<profile>
<!--不同環境Profile的唯一id-->
<id>dev</id>
<properties>
<!--profiles.active是自定義的欄位(名字隨便起),自定義欄位可以有多個-->
<profiles.active>dev</profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
</profiles>
目錄結構。
application.yml
spring:
profiles:
active: @profiles.active@
application-dev.yml中程式碼如下
server:
port: 7091
其他幾個檔案我只是把埠號進行了修改,方便打包看不同的效果。
maven打包與啟用profiles
你可以執行命令
mvn clean package -Ptest
然後啟動jar包,可以看到jar包啟動的是test的配置,如果換成-Pdev啟動的就是dev包的埠。
預設啟動方式
如果不帶-Ptest,啟動的是 prod的埠。因為在profiles中我們看到有配置預設的選項。
<activation>
<activeByDefault>true</activeByDefault>
</activation>
settings.xml中使用activeProfiles指定
<activeProfiles>
<activeProfile>profileTest1</activeProfile>
</activeProfiles>
通過IDEA的視覺化的方式
當然如果使用IDEA工具進行開發,還可以使用視覺化的方式進行打包。
更高階的玩法
通過和pom結合的方式設定動態引數
如果我們希望通過docker-maven-plugin外掛,把編譯好的jar打包成docker並且傳入相應的開發、測試、生產的伺服器中去。這個時候,我們就需要根據不同的條件去傳入不同的伺服器。
在profiles中我們可以做以下定義
<profiles>
<profile>
<id>dev</id>
<properties>
<profile.id>dev</profile.id>
<docker.host>http://dev.demo.com:2375</docker.host>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profile.id>test</profile.id>
<docker.host>http://test.demo.com375</docker.host>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profile.id>prod</profile.id>
<docker.host>http://prod.demo.com:2375</docker.host>
</properties>
</profile>
</profiles>
而在build控制元件中我們可以使用以下配置
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.1.0</version>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<imageName>demo/${project.artifactId}</imageName>
<imageTags>
<imageTag>${project.version}-${current.time}</imageTag>
<imageTag>latest</imageTag>
</imageTags>
<forceTags>true</forceTags>
<dockerHost>${docker.host}</dockerHost>
<forceTags>true</forceTags>
<baseImage>java:8</baseImage>
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
其中 ${project.artifactId} 和${project.version}是關於
${docker.host}則是我們在profiles中定義的,可以隨著我們選擇不同的profile,把jar包build成不同的docker映象,並傳入指定伺服器。
通過和yml結合設定動態引數
除了可以在pom中設定動態引數,使得其根據profile的不同選擇不同的引數。還可以通過設定不同的profile,讓yml選擇不同的引數。這點和快速上手的例子有點相似。具體如下:
設定profiles
<profiles>
<profile>
<id>dev</id>
<properties>
<profile.id>dev</profile.id>
<eureka.url>http://127.0.0.1:8001/eureka</eureka.url>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profile.id>test</profile.id>
<eureka.url>http://base-registry:8001/eureka</eureka.url>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profile.id>prod</profile.id>
<eureka.url>http://base-registry:8001/eureka</eureka.url>
</properties>
</profile>
<profile>
<id>new</id>
<properties>
<profile.id>new</profile.id>
<eureka.url>http://base-registry:8001/eureka</eureka.url>
</properties>
</profile>
</profiles>
我們在profile中設定了一個eureka.url的屬性,就可以在yml中直接呼叫。
eureka:
client:
service-url:
defaultZone: @eureka.url@
registry-fetch-interval-seconds: 10
instance:
prefer-ip-address: true
在IDEA除錯和啟動的時候,一般會報錯如下:
org.yaml.snakeyaml.scanner.ScannerException: while scanning for the next token
found character ‘@’ that cannot start any token.
解決方法就是引入yaml.sankeyaml的jar包
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
</dependency>
打包不同的資源
在profile打包yml檔案的時候,如果我們解壓了jar包,會發現還是把所有的application-profile.yml檔案給打包進去了。這個可以通過設定打包引數,只打包需要的application檔案。
<profiles>
<profile>
<id>dev</id>
<properties>
<env>dev</env>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>prd</id>
<properties>
<env>prd</env>
</properties>
</profile>
</profiles>
<build>
<finalName>springmvc</finalName>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>dev/*</exclude>
<exclude>prd/*</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources/${env}</directory>
</resource>
</resources>
</build>
目錄結構如下: