Maven Multi-environment package

Multi-environment


The project is divided into three kinds of environment:local、dev、pro。java

不一樣的環境配置不一樣,若是隻擁有一套配置的話,會致使在不一樣的環境上須要反覆的修改相同配置進行打包,好比說如今本地通過測試,須要發佈到開發環境,則須要修改配置文件,改成開發環境的配置參數,進行打包,而後又調整爲本地環境進行開發與測試。mysql

Filtering

  Filtering是maven的resource插件提供的功能,做用是對資源文件中的佔位符進行替換。稱爲maven resources filter。替換的便來來自system.properties,project proerties(pom.xml的<properties>)、filter resources(filter配置文件)和command line。替換指定目錄*.properties文件裏的佔位符(${jdbc.url}),具體使用以下:
  在src/main/resources/conf目錄有個配置文件jdbc.properties,內容以下:sql

jdbc.url=${jdbc.url}
jdbc.username=${jdbc.username}
jdbc.password=${jdbc.password}

  maven default生命週期,process-resources階段執行maven-resources-plugin的resources目標處理主資源目下的資源文件時,是否對主資源目錄開啓資源過濾apache

<resources>
    <resource>
        <directory>src/main/resources/conf</directory>
        <filtering>true</filtering>
    </resource>
</resources>

maven resource plugin開啓filtering進行佔位符替換處理。bash

例如從pom.xml的project proerties元素獲取變量replace placeholder variables。maven

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.panda.pack</groupId>
  <artifactId>bird</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  
  <!-- Define placeholder variables -->
  <properties>
	<jdbc.url>jdbc:mysql://127.0.0.1:3306/panda</jdbc.url>
	<jdbc.username>root</jdbc.username>
	<jdbc.password>panda</jdbc.password>
  </properties>
  
  <build>
        <mvn resource pulgin filtering -->
        <resources>
          <!-- scan directory -->
          <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
          </resource>
        </resources>
  </build>
</project>

execute "mvn clean package -Dmaven.test.skip=true",編譯後target directory的jdbc.properties內容爲:ide

jdbc.url=jdbc:mysql://127.0.0.1:3306/panda
jdbc.username=root
jdbc.password=panda

or filter resouces 經過將變量定義在配置文件中好比filters.properties,pom.xml:測試

<build>
    <filters>
         <!-- Define placeholder variables -->
        <filter>src/main/filters.properties</filter>
    </filters>

    <resources>
       <resource>
           <directory>src/main/resources</directory>
           <filtering>true</filtering>
       </resource>
    </resources>
</build>

filters.properties content is as follows:ui

jdbc.url=jdbc:mysql://127.0.0.1:3306/panda
jdbc.username=panda
jdbc.password=panda

Profile

Define profile

  pom.xm中的profile元素,能夠在兩個文件中配置:maven install directory/conf/settings.xml 和 pom.xml file of the project。url

  •   settings.xml中define的profile是全局的,對maven項目有效,只能定義<repositories>、<pluginRepositories>、 <properties>元素。

  • pom.xml中define的profile是局部的,只對當前pom.xml所在的項目有效。

Using a profile

  maven 的-P參數指定profile,參數的值是profile的id,多個profile以逗號分割,若是不想激活某個默認的profile,在id前加個!。

  mvn clean package -Dmaven.test.skip=true -Plocal,dev,!pro (ignore production profile)

IDEA裏則能夠在 Maven Projects 裏直接勾選想要激活的profile

Or Define profile時, <profile> 的 <activation> 元素下配置默認的profile。

pom.xml:

<!-- default use local profile-->
<profiles>
  <profile>
     <id>local</id>
        <properties>
            <active.profile>local</active.profile>
        </properties>
     <activation>
        <activeByDefault>true</activeByDefault>
     </activation>
  </profile>
</profiles>

  settings.xml文件經過<activeProfiles>配置default use的profile列表。

<activeProfiles>
    <activeProfile>profile ids</activeProfile>
</activeProfiles>

Example

pom.xml

<project>
	<profiles>
		<profile>
			<id>dev</id>
			<properties>
				<active.profile>local</active.profile>
				<jdbc.url>jdbc:mysql://127.0.0.1:3306/local</jdbc.url>
				<jdbc.username>root</jdbc.username>
				<jdbc.password>local</jdbc.password>
			</properties>
			<!-- Set the current configuration for the default profile -->
			<activation>
				<activeByDefault>true</activeByDefault>
			</activation>
		</profile>
		  
		<profile>
			<id>pro</id>
			<properties>
				<profiles.active>dev</profiles.active>
				<jdbc.url>jdbc:mysql://127.0.0.1:3306/dev</jdbc.url>
				<jdbc.username>root</jdbc.username>
				<jdbc.password>dev</jdbc.password>
			</properties>
		</profile>
		  
		<profile>
			<id>pro</id>
			<properties>
				<profiles.active>pro</profiles.active>
				<jdbc.url>jdbc:mysql://127.0.0.1:3306/pro</jdbc.url>
				<jdbc.username>root</jdbc.username>
				<jdbc.password>pro</jdbc.password>
			</properties>
		</profile>
	</profiles>
  
	<build>
		<resources>
			<resource>
				<directory>src/main/resources</directory>
				<filtering>true</filtering>
			</resource>
        </resources>	
	</build>
</project>

  使用不一樣Profile 的<properties> variables進行佔位符替換。以上方式是將佔位符變量值定義在profile的<properties>元素中進行替換,這樣不方便維護,建議設置在相應配置文件中。

<project>
	<profiles>
		<profile>
			<id>dev</id>
			<properties>
				<active.profile>local</active.profile>
			</properties>
			<!-- Set the current configuration for the default profile -->
			<activation>
				<activeByDefault>true</activeByDefault>
			</activation>
		</profile>	
		<profile>
			<id>dev</id>
			<properties>
				<active.profile>dev</active.profile>
			</properties>
		</profile>
		<profile>
			<id>pro</id>
			<properties>
				<active.profile>pro</active.profile>
			</properties>
		</profile>
	</profiles>
  
	<build>
		<filters>
			<!-- active.profile is current evironment profiles.active -->
			<filter>src/main/filters-${active.profile}.properties</filter>
		</filters>
		<resources>
			<resource>
			  <directory>src/main/resources</directory>
			  <filtering>true</filtering>
			</resource>
		</resources>	
	</build>
</project>

  上圖中的<filter>的"${ative.profile}"佔位符指向的是<profile>元素中<properties> 的<active.profile>元素,此值能夠任意定義。

  在Project路徑src/main中Create三個文件:filters-local.properties、filters-dev.properties、filters-pro.properties。

filters-local.properties:

jdbc.url=jdbc:mysql://127.0.0.1:3306/local
jdbc.username=root
jdbc.password=local

  其他兩個配置文件filters-local.properties和filters-pro.properties與之相似。

  配置在配置文件中方便維護,使用不一樣的Profile,則替換相應的Profile的{active.profile}.properties的變量。

execute 

mvn clean package -Dmaven.test.skip=true -Plocal

  執行以上命令,將會使用local profile的配置文件filters-local.properties的變量值進行打包,若是默認不傳遞-P參數,則會使用default profile。

上面的方式是定義配置文件時,使用佔位符,而後再定義相應的幾種環境的正式配置文件,對佔位符文件進行替換。例如上面的例子,須要使用的配置文件由以下幾個:

filters.properties:佔位符定義文件

filters-local.properties、filters-dev.properties、filters-pro.properties三種環境的配置文件。使用佔位符進行替換,有些不方便。對於大型複雜項目來講容易出現錯誤。

推薦使用Resources

 

Resources

  此種方式不進行佔位符文件替換,同時不須要定義佔位符文件。經過定義不一樣的文件夾目錄放置不一樣環境須要的配置文件,在打包或發佈時指定環境,解壓指定環境目錄的配置文件至指定目錄,此處是WEB/classes。

src/main/resources目錄結構 as follow:

 

pom.xml as follows:

<project>
<profiles>
  	<profile>
  		<id>dev</id>
  		<properties>
  			<profiles.active>dev</profiles.active>
  		</properties>
  		<activation>
            <activeByDefault>true</activeByDefault>
        </activation>
  	</profile>
  	<profile>
  		<id>test</id>
  		<properties>
  			<profiles.active>test</profiles.active>
  		</properties>
  	</profile>
  	<profile>
  		<id>prod</id>
  		<properties>
  			<profiles.active>prod</profiles.active>
  		</properties>
  	</profile>
  </profiles>
  
  <build>
  	<resources>
  		<resource>
  			  <!-- 
		                  資源文件位置src/main/resources/,這下面的資源文件的${}會所有被替換成filter中的標籤內容。
		                  directory指定的value會做爲classes的資源跟目錄,
		                  好比指定:src/main/resources/,則classes下會出現jdbc等包,
		                  若指定:src/main/resources/jdbc/,則classes下直接出現jdbc包下的文件,不會額外出現jdbc等其餘包結構。由於他把jdbc做爲了根目錄
              -->
  			 <directory>src/main/resources</directory>
  			 <!-- 在某個resource中若是設置filtering爲true,將會根據輸入參數動態修改相關內容。 -->
  			 <filtering>true</filtering>
             <!-- 資源根目錄排除各環境的配置,使用單獨的資源目錄來指定 -->  
             <excludes>  
             	<exclude>test/*</exclude>
                <exclude>dev/*</exclude>  
                <exclude>prod/*</exclude> 
             </excludes>  
  		</resource>
  		<resource>  
            <!-- 根據參數指定資源目錄 -->  
            <directory>src/main/resources/${profiles.active}</directory>  
            <!-- 指定編譯後的目錄即生成文件位置(默認爲WEB-INF/class)
            <targetPath>config</targetPath> -->  
        </resource>  
  	</resources>
  </build>

  <plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<version>3.5.1</version>
			<configuration>
				<source>1.7</source>
				<target>1.7</target>
				<encoding>UTF-8</encoding>  
			</configuration>
		</plugin>
  </plugins>
  
</project>

上面的配置中關鍵的在於<resources>元素中的<directory>的佔位符src/main/resoruces/${profiles.active}。此處的profiles.active是<profile>中定義的元素。

不一樣環境的配置文件在不一樣的文件夾中,也就是不一樣的<profile>中,方便單獨維護,使用不一樣的Profile,則會將相對應目錄的Profile的profiles.active變量,傳遞給<resources>的directory元素。例如以下: 

mvn clean package -Dmaven.test.skip=true -Pprod

  執行以上命令,將會使用profile爲prod對應的文件夾目錄的配置文件進行打包。變量的值同時以下所示:

<resource>  
  <directory>src/main/resources/prod</directory>
</resource>

換句話說就是打包prod環境的配置文件至WEB-INF/classes(如不指定<target>元素,則默認爲此目錄)。

相關文章
相關標籤/搜索