使用maven的profile切換專案各環境的引數

bingguang1993發表於2018-05-07

在實際開發專案中,常常有幾種環境,一般情況下最少有三種環境:開發測試正式。

各個環境之間的引數各不相同,比如mysql、redis等不同環境的host不一樣,若每個環境都手動替換環境很容易出錯,這裡我們利用maven的profile功能切換環境。


本文的專案結構圖:



src/main/resources/dev  目錄的properties是開發環境的配置專案
src/main/resources/test  目錄的properties是測試環境的配置專案


在pom.xml定義環境的profile
[html] view plain copy
  1. <profiles>  
  2.     <profile>  
  3.         <id>dev</id>  
  4.         <properties>  
  5.             <profiles.activation>dev</profiles.activation>  
  6.         </properties>  
  7.         <activation>  
  8.             <activeByDefault>true</activeByDefault>  
  9.         </activation>  
  10.     </profile>  
  11.     <profile>  
  12.         <id>test</id>  
  13.         <properties>  
  14.             <profiles.activation>test</profiles.activation>  
  15.         </properties>  
  16.     </profile>  
  17. </profiles>  

activeByDefault標籤的值為true的話表示預設的profile,使用mvn install命令起作用的就是它,這裡為dev


resources標籤定義要包含的資源,在下面的配置下package階段會把resources資料夾裡的 ${profiles.activation}/* 檔案打包
這裡的${profiles.activation}由命令maven的-P選項指定,例:mvn install -Ptest 就是打包 test/* 即test目錄下的所有檔案 
[html] view plain copy
  1. <resources>  
  2.     <resource>  
  3.         <directory>src/main/resources</directory>  
  4.         <!-- **/*.properties 是指包括根目錄或子目錄所有properties型別的檔案 -->  
  5.         <includes>  
  6.             <include>**/*.properties</include>  
  7.             <include>**/*.xml</include>  
  8.         </includes>  
  9.   
  10.         <!-- 排除dev、test目錄下的檔案 -->  
  11.         <excludes>  
  12.             <exclude>dev/*</exclude>  
  13.             <exclude>test/*</exclude>  
  14.         </excludes>  
  15.     </resource>  
  16.     <resource>  
  17.         <directory>src/main/resources</directory>  
  18.         <!-- 包含,若沒有指定則預設為 activeByDefault 標籤定義的profile -->  
  19.         <includes>  
  20.             <include>${profiles.activation}/*</include>  
  21.         </includes>  
  22.     </resource>  
  23. </resources>  





applicationContext.xml檔案如下
[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.        xmlns:context="http://www.springframework.org/schema/context"  
  5.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  6.         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-autowire="byType">  
  7.   
  8.     <!-- Annotation Config -->  
  9.     <context:annotation-config/>  
  10.   
  11.   
  12.     <!-- 取${profiles.activation:dev}表示取${profiles.activation}的值,若沒有則指定dev -->  
  13.     <bean id="propertyConfig"  
  14.           class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
  15.         <property name="locations">  
  16.             <list>  
  17.                 <value>classpath:${profiles.activation:dev}/jdbc.properties</value>  
  18.             </list>  
  19.         </property>  
  20.     </bean>  
  21.   
  22.     <!-- ==============配置資料來源============== -->  
  23.     <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">  
  24.         <!-- 基本屬性 url、user、password -->  
  25.         <property name="url" value="${jdbc.url}" />  
  26.         <property name="username" value="${jdbc.username}" />  
  27.         <property name="password" value="${jdbc.password}" />  
  28.   
  29.         <!-- 配置初始化大小、最小、最大 -->  
  30.         <property name="initialSize" value="1" />  
  31.         <property name="minIdle" value="1" />  
  32.         <property name="maxActive" value="20" />  
  33.   
  34.         <!-- 配置獲取連線等待超時的時間 -->  
  35.         <property name="maxWait" value="60000" />  
  36.   
  37.         <!-- 配置間隔多久才進行一次檢測,檢測需要關閉的空閒連線,單位是毫秒 -->  
  38.         <property name="timeBetweenEvictionRunsMillis" value="60000" />  
  39.   
  40.         <!-- 配置一個連線在池中最小生存的時間,單位是毫秒 -->  
  41.         <property name="minEvictableIdleTimeMillis" value="300000" />  
  42.   
  43.     </bean>  
  44.   
  45. </beans>  

這裡取${profiles.activation:dev}是取${profiles.activation}的值,若不存在,則預設為dev;
若值為dev,locations的值為classpath:dev/jdbc.properties。
${profiles.activation}是在web.xml裡的context-param取值
[html] view plain copy
  1. <context-param>  
  2.     <param-name>profiles.activation</param-name>  
  3.     <param-value>${profiles.activation}</param-value>  
  4. </context-param>  

值得注意的是,${profiles.activation}由於有預設值的存在,applicationContext.xml不需要啟動web容器去讀取web.xml中的${profiles.activation},
這有效的保障了使用JUnit進行單元測試,也就是說在maven的test目錄裡的測試用例可以正常執行。

現在的問題就成了如何把maven裡啟用的profile值傳進來,使用maven-war-plugin能在maven install的時期會設定web.xml佔位符值${}的值 
[html] view plain copy
  1. <plugin>  
  2.       <groupId>org.apache.maven.plugins</groupId>  
  3.           <artifactId>maven-war-plugin</artifactId>  
  4.       <configuration>  
  5.           <warName>${profiles.activation}</warName>  
  6.           <!-- 啟用spring profile -->  
  7.           <webResources>  
  8.               <resource>  
  9.                   <filtering>true</filtering>  
  10.                   <directory>src/main/webapp</directory>  
  11.                   <includes>  
  12.                       <include>**/web.xml</include>  
  13.                   </includes>  
  14.               </resource>  
  15.           </webResources>  
  16.           <warSourceDirectory>src/main/webapp</warSourceDirectory>  
  17.           <webXml>src/main/webapp/WEB-INF/web.xml</webXml>  
  18.       </configuration>  
  19.   </plugin>  



所有檔案配置完畢,使用  mvn install -P{profile} 命令打包war
example:     
1、mvn install               沒有指定profile,預設為dev
2、mvn install -Ptest -Dmaven.test.skip=true   指定profile為test並跳過測試

在使用tomcat部署時,先使用maven的命令切換至目標環境,然後tomcat的目標目錄設定為編譯後的target/${project.actifact}目錄(大多數IDE比如eclipse和IDEA都是這樣)

相關文章