1. 程式人生 > 實用技巧 >Maven詳細教程

Maven詳細教程

前言

本文可以幫助你加深對Maven的整體認識,不是一篇基礎文章。如果你現在還沒有用 Maven 跑過 HelloWorld,那麼本文可能不適合你。

一、Maven簡介

Maven 官網:https://maven.apache.org
Maven 3.3.9版本文件:http://maven.apache.org/ref/3...

Maven是一個專案管理工具,它包含了一個專案物件模型 (Project Object Model),一組標準集合,一個專案生命週期(Project Lifecycle),一個依賴管理系統(Dependency Management System),和用來執行定義在生命週期階段(phase)中外掛(plugin)目標(goal)的邏輯。

  1. 版本:maven有自己的版本定義和規則
  2. 構建:可以完成編譯,打包,部署等。
  3. 依賴管理:方便引入所需依賴 Jar 包,不需手動下載
  4. 文件生成:maven的site命令支援各種文件資訊的釋出,包括構建過程的各種輸出,javadoc,產品文件等。
  5. 專案關係:一個大型的專案通常有幾個小專案或者模組組成,用maven可以很方便地管理

二、Maven生命週期

maven把專案的構建劃分為不同的生命週期(lifecycle)。粗略一點的話,它這個過程(phase)包括:

  1. 驗證(validate):驗證專案是否正確
  2. 編譯(compile): 編譯專案的原始碼
  3. 測試(test):使用合適的單元測試框架測試編譯的原始碼。這些測試不應該要求程式碼被打包或部署
  4. 打包(package)
  5. 驗證(verify)
  6. 安裝(install)
  7. 部署(deploy)

maven中所有的執行動作(goal)都需要指明自己在這個過程中的執行位置,然後maven執行的時候,就依照過程的發展依次呼叫這些goal進行各種處理。

這個也是maven的一個基本排程機制。一般來說,位置稍後的過程都會依賴於之前的過程。當然,maven同樣提供了配置檔案,可以依照使用者要求,跳過某些階段。

三、Maven 版本規範

maven使用如下幾個要素來唯一定位某一個輸出物: groupId:artifactId:packaging:version 。比如org.springframework:spring:2.5 。每個部分的解釋如下:

  1. groupId 公司,團體等。如Apache Software的專案有以org.apache開頭的groupId。
  2. artifactId 專案的唯一識別符號。比如一個helloworld專案就叫helloworld。
  3. packaging 專案打包輸出的型別,預設是jar。型別為war的專案產生一個web應用。
  4. version 一個專案的特定版本。釋出的專案有一個固定的版本標識來指向該專案的某一個特定的版本。而正在開發中的專案可以用一個特殊的標識,這種標識給版本加上一個"SNAPSHOT"的標記。

    • maven有自己的版本規範,一般是如下定義<major version>.<minor version>.<incremental version>-<qualifier>,比如1.2.3-beta-01。要說明的是,maven自己判斷版本的演算法是major,minor,incremental部分用數字比較,qualifier部分用字串比較,所以要小心 alpha-2和alpha-15的比較關係,最好用 alpha-02的格式。
    • maven在版本管理時候可以使用幾個特殊的字串 SNAPSHOT ,LATEST ,RELEASE 。比如"1.0-SNAPSHOT"。各個部分的含義和處理邏輯如下說明:

      • SNAPSHOT 如果一個版本包含字串"SNAPSHOT",Maven就會在安裝或釋出這個元件的時候將該符號展開為一個日期和時間值,轉換為UTC時間。例如,"1.0-SNAPSHOT"會在2010年5月5日下午2點10分發布時候變成1.0-20100505-141000-1。這個詞只能用於開發過程中,因為一般來說,專案組都會頻繁釋出一些版本,最後實際釋出的時候,會在這些snapshot版本中尋找一個穩定的,用於正式釋出,比如1.4版本釋出之前,就會有一系列的1.4-SNAPSHOT,而實際釋出的1.4,也是從中拿出來的一個穩定版。
      • LATEST 指某個特定構件的最新發布,這個釋出可能是一個釋出版,也可能是一個snapshot版,具體看哪個時間最後。
      • RELEASE 指最後一個釋出版。

四、Maven 專案依賴

1. 多模組依賴和繼承

專案結構圖:

parent
    ├─childA(model層)
    │  └─pom.xml(jar)
    ├─childB(web層)
    │  └─pom.xml(war)
    └─pom.xml(pom)
  1. parent中執行mvn install就能將 childA和childB 一起編譯

    parent的pom.xml做如下配置:

    <groupId>com.song</groupId>
    <artifactId>parent</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>    <!-- pom表示它是一個被繼承的模組 -->
    
    <modules>
        <module>childA</module>   <!-- 不加module則不會被聯合編譯 -->
        <module>childB</module>
    </modules>

    childA和childB的pom.xml都需要配置parent,防止引入的包衝突(如果不加parent,會分別去編譯他們引入的依賴,會重複引入包):

    <!-- childA 的 pom.xml-->
    <parent>
        <artifactId>parent</artifactId>
        <groupId>com.song</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>childA</artifactId>
    <packaging>jar</packaging>
    
    <!-- childB 的 pom.xml-->
    <parent>
        <artifactId>parent</artifactId>
        <groupId>com.song</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>
    <artifactId>childB</artifactId>
    <packaging>war</packaging>
  2. 子pom間存在引用關係,比如childB引用到了childA的jar包
<dependency>
   <groupId>com.module</groupId>
   <artifactId>childA</artifactId>       <!--加上childA的依賴-->
   <version>1.0-SNAPSHOT</version>
</dependency>

2. 子專案繼承父專案的依賴

parent中加上<dependencyManagement>,child專案就可以繼承parent專案的依賴,並且在child中可以不用加version了。

<dependencyManagement>
   <dependencies>
      <dependency>
           <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
          <version>2.5</version>
      </dependency>
   </dependencies>
</dependencyManagement>

3. 依賴範圍

如果不顯示執行 <scope> 屬性時,預設<scope>compile</scope>
scope 屬性包括:

  1. compile(編譯範圍):編譯範圍的<dependency>在所有的classpath中可用,同時它們也會被打包
  2. provided(已提供範圍):表示部署的環境當中有某容器已經提供了該jar包,只在編譯classpath(不是執行時)可用。它們不是傳遞性的,也不會被打包。例如,如果你開發了一個web應用,你可能在編譯classpath中需要可用的Servlet API來編譯一個servlet,但是你不會想要在打包好的WAR中包含這個Servlet API;這個Servlet API JAR由你的servlet容器(Tomcat)提供。
  3. runtime(執行時範圍):只在執行和測試系統的時候需要,但在編譯的時候不需要。
  4. test(測試範圍):在一般的 編譯和執行時都不需要,它們只有在測試編譯和測試執行階段可用。
  5. system(系統範圍):該範圍不推薦使用(你應該一直儘量去從公共或定製的Maven倉庫中引用依賴)
詳細可參考:https://maven.apache.org/guid...

4. 可選依賴(Optional Dependencies)和依賴排除(Dependency Exclusions)

maven的依賴關係是有傳遞性的。如:A-->B,B-->C。但有時候,專案A可能不是必需依賴C,因此需要在專案A中排除對A的依賴。在maven的依賴管理中,有兩種方式可以對依賴關係進行,分別是可選依賴(Optional Dependencies)以及依賴排除(Dependency Exclusions)。

4.1 可選依賴 optional

當一個專案A依賴另一個專案B時,專案A可能很少一部分功能用到了專案B,此時就可以在A中配置對B的可選依賴。舉例來說,一個類似hibernate的專案,它支援對mysql、oracle等各種資料庫的支援,但是在引用這個專案時,我們可能只用到其對mysql的支援,此時就可以在這個專案中配置可選依賴。

配置可選依賴的原因:1、節約磁碟、記憶體等空間;2、避免license許可問題;3、避免類路徑問題,等等。

<dependency>
  <groupId>sample.ProjectB</groupId>
  <artifactId>Project-B</artifactId>
  <version>1.0</version>
  <scope>compile</scope>
  <optional>true</optional>
</dependency>

假設以上配置是專案A的配置,即:Project-A --> Project-B。在編譯專案A時,是可以正常通過的。

如果有一個新的專案X依賴A,即:Project-X -> Project-A。此時專案X就不會依賴專案B了。如果專案X用到了涉及專案B的功能,那麼就需要在pom.xml中重新配置對專案B的依賴。

4.2 依賴排除 exclusions

當一個專案A依賴專案B,而專案B同時依賴專案C,如果專案A中因為各種原因不想引用專案C,在配置專案B的依賴時,可以排除對C的依賴。

示例(假設配置的是A的pom.xml,依賴關係為:A --> B; B --> C):

<dependency>
  <groupId>sample.ProjectB</groupId>
  <artifactId>Project-B</artifactId>
  <version>1.0</version>
  <scope>compile</scope>
  <exclusions>
    <exclusion>
      <groupId>sample.ProjectC</groupId>
      <artifactId>Project-C</artifactId>
    </exclusion>
  </exclusions> 
</dependency>

當然,對於多重依賴,配置也很簡單,參考如下示例:

Project-A
   -> Project-B
        -> Project-D 
              -> Project-E <! -- This dependency should be excluded -->
              -> Project-F
   -> Project C

A對於E相當於有多重依賴,我們在排除對E的依賴時,只需要在配置B的依賴中進行即可:

<dependency>
  <groupId>sample.ProjectB</groupId>
  <artifactId>Project-B</artifactId>
  <version>1.0-SNAPSHOT</version>
  <exclusions>
    <exclusion>
      <groupId>sample.ProjectE</groupId>
      <artifactId>Project-E</artifactId>
    </exclusion>
  </exclusions>
</dependency>

五、Maven外掛機制

1. Maven預設外掛

不配置Plugin時,Maven預設會使用以下外掛。如果針對各個 plugin 有特殊配置的話,需要顯示指定 plugin 和 屬性配置。

pluginfunctionlife cycle phase
maven-clean-plugin 清理上一次執行建立的target檔案 clean
maven-resources-plugin 處理資原始檔 resources,testResources
maven-compiler-plugin 編譯Java程式碼 compile、testCompile
maven-surefire-plugin 執行單元測試檔案 test
maven-jar-plugin 建立 jar package
maven-install-plugin 拷貝jar到本地的maven倉庫 .m2/repository 下面 install
maven-deploy-plugin 釋出 jar deploy
maven-site-plugin 生成文件 site
maven-site-plugin:將工程所有文件生成網站,生成的網站介面預設和apache的專案站點類似,但是其文件用doxia格式寫的,目前不支援docbook,需要用其他外掛配合才能支援。需要指出的是,在maven 2.x系列中和maven3.x的site命令處理是不同的,在舊版本中,用 mvn site 命令可以生成reporting節點中的所有報表,但是在maven3中,reporting過時了,要把這些內容作為 maven-site-plugin的configuration的內容才行。詳細內容可以參考http://www.wakaleo.com/blog/2...
<build>
    <!-- resources 是 maven-resources-plugin 的-->
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <filtering>true</filtering> <!-- filtering 用來表示資原始檔中的佔位符是否需要被profiles中的屬性動態替換,true為需要替換。 -->
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*.properties</include>
                <include>*.xml</include>
                <include>*.dic</include>
                <include>*.txt</include>
            </includes>
        </resource>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
            <includes>
                <include>*.p12</include>
            </includes>
        </resource>
    </resources>



    <plugins>
        <!-- 
            maven-compiler-plugin編譯原始碼。
            指定maven編譯的jdk版本,如果不指定,maven3預設用jdk 1.5 maven2預設用jdk1.3 
            windows預設使用GBK編碼,java專案經常編碼為utf8,也需要在compiler外掛中指出,否則中文亂碼可能會出現編譯錯
        -->
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
        
        <!--
            maven-resources-plugin用來處理資原始檔,預設的主資原始檔目錄是src/main/resources。
        -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-resources-plugin</artifactId>
            <version>2.6</version>
            <configuration>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
    </plugins>
</build>

2. Maven常用外掛

2.0 spring-boot-maven-plugin

當使用SpringBoot開發專案的時候,會使用到spring-boot-maven-plugin外掛

官方文件:https://docs.spring.io/spring...

Spring Boot Maven plugin有5個Goals:

命令說明
spring-boot:repackage 預設goal。在mvn package之後,再次打包可執行的jar/war,<br/>並將mvn package生成的軟體包重新命名為*.original
spring-boot:run 執行Spring Boot應用
spring-boot:start 在mvn integration-test階段,進行Spring Boot應用生命週期的管理
spring-boot:stop 在mvn integration-test階段,進行Spring Boot應用生命週期的管理
spring-boot:build-info 生成Actuator使用的構建資訊檔案build-info.properties

其中比較重要的命令是:

mvnpackagespring-boot:repackage

執行後會看到生成的兩個jar檔案,一個是*.jar,另一個是*.jar.original
這是由於在執行上述命令的過程中,Maven首先在package階段打包生成*.jar檔案;然後執行spring-boot:repackage重新打包

我們也可以跳過repackage階段:

cleandeploy -D spring-boot.repackage.skip=true

加上-D spring-boot.repackage.skip=true引數即可,此時只會生成一個普通的jar包

2.1 maven-source-plugin

maven-source-plugin提供專案自動將原始碼打包併發布的功能,在需要釋出原始碼專案的pom.xml檔案中新增如下程式碼即可:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <configuration>
    </configuration>
    <executions>
        <execution>
            <id>attach-sources</id>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

執行mvn install,maven會自動將source install到repository 。
執行mvn deploy,maven會自動將source deploy到remote-repository 。
執行mvn source:jar,單獨打包原始碼。

注意:在多專案構建中,將source-plugin置於頂層或parent的pom中並不會發揮作用,必須置於具體專案的pom中。

2.2 Tomcat外掛

tomcat外掛有兩種:tomcat-maven-plugin 和 tomcat7-maven-plugin,使用方式基本相同。

  • tomcat-maven-plugin 外掛是org.codehaus.mojo組織提供的,裡面的tomcat是6.0.29版本,沒有更新了。
  • tomcat7-maven-plugin 外掛是apache提供的,官網:http://tomcat.apache.org/mave...
  1. tomcat7-maven-plugin 外掛使用

    <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
           <configuration>
              <path>/</path>
              <port>8080</port>
              <uriEncoding>UTF-8</uriEncoding>
              <server>tomcat7</server>
           </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>run</goal>
                    </goals>
                </execution>
            </executions>
    </plugin>

    命令:

    tomcat7:deploy  --部署一個web war包
    tomcat7:reload  --重新載入web war包
    tomcat7:start    --啟動tomcat
    tomcat7:stop    --停止tomcat
    tomcat7:undeploy --停止一個war包
    tomcat7:run --啟動嵌入式tomcat ,並運行當前專案
  2. tomcat-maven-plugin 外掛使用

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>tomcat-maven-plugin</artifactId>
        <version>1.1</version>
        <configuration>
            <path>/helloworld</path>
            <port>8080</port>
            <uriEncoding>UTF-8</uriEncoding>
            <url>http://localhost:8080/manager/html</url>
            <server>tomcat6</server>
            <systemProperties>
                <JAVA_OPTS>-Xms256m -Xmx512m -XX:MaxPermSize=512m</JAVA_OPTS>
              </systemProperties>
        </configuration>
    </plugin>

    命令:

    tomcat:deploy   --部署一個web war包
    tomcat:reload   --重新載入web war包
    tomcat:start    --啟動tomcat
    tomcat:stop    --停止tomcat
    tomcat:undeploy --停止一個war包
    tomcat:run  --啟動嵌入式tomcat ,並運行當前專案

配置引數:
path:是訪問應用的路徑
port:是tomcat 的埠號
uriEncoding:URL按UTF-8進行編碼,這樣就解決了中文引數亂碼。
Server:指定tomcat名稱。

2.3 自動部署外掛wagon

自動部署包含三個步驟:
編譯打包、上傳到伺服器、在伺服器上執行linux命令

2.3.1 檔案上傳到伺服器

Maven專案可使用 mvn install 指令打包,打包完成後包位於target目錄下,要想在遠端伺服器上部署,首先要將包上傳到伺服器。

首先在本地的setting.xml中配置server的資訊,包括id,使用者名稱,密碼。(當然也可以在pom.xml裡面配置)

<servers>
    <server>
      <id>linux_server</id>
      <username>user</username>
      <password>password</password>
    </server>
</servers>

pom.xml

<build>
    <extensions>
        <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ssh</artifactId>
            <version>2.8</version>
        </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>wagon-maven-plugin</artifactId>
            <version>1.0</version>
            <configuration>
                <serverId>linux_server</serverId>
                <fromFile>target/test.war</fromFile>
                <url>scp://user:[email protected]/home/tomcat7/webapps</url>
            </configuration>
        </plugin>
    </plugins>
</build>

<serverId>linux_server</serverId>: 在setting.xml中配置的server的id名字
<fromFile>target/test.war</fromFile>:是要上傳到伺服器的檔案,一般來說是jar或者war包<url>scp://user:[email protected]/home/tomcat7/webapps</url>:配置伺服器的使用者、密碼、地址以及檔案上傳的目錄

命令:

# 對專案進行打包和上傳操作
mvn clean install wagon:upload-single 

如果覺的wagon命令太長,可以設定 excutions 來配置phase和goals來簡化命令。

2.3.2 在伺服器上執行linux命令

1. 執行jar檔案
<!-- 
如果執行的命令中沒有“-D maven.deploy.skip=true”不配置distributionManagement 則會報錯:-DaltDeploymentRepository=id::layout::url parameter 因為不加maven.deploy.skip=true,則會使用maven的deploy,又使用wagon的deploy。而maven的deploy是需要配置distributionManagement的
<distributionManagement>
    <repository>
        <id>${serverid}</id>
        <url>scp://192.168.20.128/home/java/exe</url>
    </repository>
</distributionManagement>
-->

<build>
    <extensions>
        <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ssh</artifactId>
            <version>2.8</version>
        </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>wagon-maven-plugin</artifactId>
            <version>1.0</version>
            
            <configuration>
                <fromFile>target/test.jar</fromFile>
                <url>scp://user:[email protected]/home/java/exe</url>
                <commands>
                    <command>pkill -f /home/java/exe/test.jar</command>  <!-- 殺死原來的程序,-f 是用來查詢命令引數,禁止使用pkill java來殺死程序,也可以是 pkill -f test.jar -->
                    <command>nohup java -jar /home/java/exe/test.jar > /home/java/exe/$(date +%Y%m%d-%H%M%S).log &amp; </command> <!-- 重新啟動test.jar,&amp; 是xml的轉義字元,表示 &-->
                </commands>
                <displayCommandOutputs>true</displayCommandOutputs> <!-- 顯示執行命令的輸出結果 -->
            </configuration>
        </plugin>
    </plugins>
</build>

命令

<!--install、wagon:upload-single、wagon:sshexec 分別對專案進行打包、上傳、執行command命令的操作-->
mvn clean install wagon:upload-single wagon:sshexec
2. 上傳war包並啟動Tomcat
<build>
   <extensions>
       <extension>
           <groupId>org.apache.maven.wagon</groupId>
           <artifactId>wagon-ssh</artifactId>
           <version>2.8</version>
       </extension>
   </extensions>
   <plugins>
       <plugin>
           <groupId>org.codehaus.mojo</groupId>
           <artifactId>wagon-maven-plugin</artifactId>
           <version>1.0</version>
           
           <configuration>
               <fromFile>target/javawebdeploy.war</fromFile>
               <url>scp://user:[email protected]/home/tomcat7/webapps</url>
               <commands>
                   <!-- 重啟Tomcat -->
                   <command>sh /home/tomcat7/bin/shutdown.sh</command>
                   <command>rm -rf /home/tomcat7/webapps/test</command>
                   <command>sh /home/tomcat7/bin/startup.sh</command>
               </commands>
               <displayCommandOutputs>true</displayCommandOutputs>
           </configuration>
       </plugin>
   </plugins>
</build>

命令

mvncleaninstallwagon:upload-singlewagon:sshexec

2.3.3 配置execution

如果覺得mvn clean package wagon:upload-single wagon:sshexec命令太長了不好記,那麼可以配置execution,在執行deploy的同時執行upload-single和sshexec。

<build>
    <extensions>
        <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ssh</artifactId>
            <version>2.8</version>
        </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>wagon-maven-plugin</artifactId>
            <version>1.0</version>
            <executions>
                <execution>
                    <id>upload-deploy</id>
                    <!-- 執行deploy命令時同時執行upload-single和sshexec -->
                    <phase>deploy</phase>
                    <goals>
                        <goal>upload-single</goal>
                        <goal>sshexec</goal>
                    </goals>
                    
                    <configuration>
                        <fromFile>target/test.war</fromFile>
                        <url>scp://user:[email protected]/home/tomcat7/webapps</url>
                        <commands>
                            <command>sh /home/tomcat7/bin/shutdown.sh</command>
                            <command>rm -rf /coder/tomcat7/webapps/test</command>
                            <command>sh /coder/tomcat7/bin/startup.sh</command>
                        </commands>
                        <displayCommandOutputs>true</displayCommandOutputs>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

部署命令

<!-- 即可使用mvn clean package來代替mvn clean package wagon:upload-single wagon:sshexec -->

<!--  必須加 -D maven.deploy.skip=true ,表示跳過maven自身的deploy使用wagon的deploy。否則報錯“-DaltDeploymentRepository=id::layout::url parameter”  -->
mvn clean deploy -D maven.deploy.skip=true

2.3.4. 完整示例配置

首先在本地的setting.xml中配置server的資訊,包括id,使用者名稱,密碼。(當然也可以在pom.xml裡面配置)

<servers>
    <server>
      <id>linux_server</id>
      <username>user</username>
      <password>password</password>
    </server>
</servers>

pom.xml


<build>
    <extensions>
        <extension>
            <groupId>org.apache.maven.wagon</groupId>
            <artifactId>wagon-ssh</artifactId>
            <version>2.8</version>
        </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>wagon-maven-plugin</artifactId>
            <version>1.0</version>
            
            <configuration>
                <serverId>linux_server</serverId>
                <url>scp://192.168.20.128/home/tomcat7/webapps</url>
                <displayCommandOutputs>true</displayCommandOutputs> <!-- 顯示執行命令的輸出結果 -->
            </configuration>
            
            <executions>
                <!-- 將war包上傳到伺服器並重啟伺服器 -->
                <execution>
                    <id>upload-war-to-server</id>
                    <phase>deploy</phase>
                    <goals>
                        <goal>upload-single</goal>
                        <goal>sshexec</goal>
                    </goals>
                    <configuration>
                        <fromFile>target/test.war</fromFile>
                        <commands>
                            <command>datefilename=$(date +%Y%m%d-%H%M%S);cp /home/tomcat7/webapps/test.war /home/tomcat7/webapps/test.war.$datefilename</command>  <!--備份舊的war包-->
                            <command>ps -ef | grep /home/tomcat7/ | grep -v grep | awk {'print $2'} | sed -e "s/^/kill -9 /g" | sh</command> <!-- 關閉tomcat7 -->
                            <command>rm -rf /home/tomcat7/webapps/test</command> <!-- 刪除test專案 -->
                            <command>export JAVA_HOME=/home/jdk/jdk1.8.0_91;sh /home/tomcat7/bin/startup.sh</command> <!-- 啟動tomcat -->
                        </commands>
                    </configuration>
                </execution>
        </plugin>
    </plugins>
</build>

部署命令

# 必須加 -D maven.deploy.skip=true ,表示跳過maven自身的deploy使用wagon的deploy。否則報錯“-DaltDeploymentRepository=id::layout::url parameter”
mvn clean deploy -D maven.deploy.skip=true

2.4 maven-war-plugin

Maven打包時可以對web.xml中的spring.profiles.active值進行替換。

web.xml中配置一個佔位符${profiles.active}:

<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>${profiles.active}</param-value>
</context-param>

pom.xml配置maven-war-plugin

<!-- 打war包時替換佔位符 -->
<build>
  <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.2.2</version>
    <configuration>
      <!-- 過濾Deployment Descriptor並將檔案中的佔位符替換為pom.xml中對應的<properties>值 -->
      <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
    </configuration>
  </plugin>
</build>

<!-- 預設的maven profile -->
<properties>
  <profiles.active>dev</profiles.active>
</properties>

<profiles>
  <profile>
    <id>dev</id>
    <properties>
      <profiles.active>dev</profiles.active>
    </properties>
  </profile>
  <profile>
    <id>release</id>
    <properties>
      <profiles.active>release</profiles.active>
    </properties>
  </profile>
</profiles>

以上配置完成後,再通過mvn package -Pdevmvn package -Preelase打包後,${profiles.active}<佔位符就被替換為devrelease

六、Maven控制測試環境和正式環境

6.1 Maven profiles切換測試環境和正式環境

<profiles>
    <profile>
        <!-- 本地開發環境 -->
        <id>dev</id>
        <properties>
            <profiles.active>dev</profiles.active>
        </properties>
        <activation>
            <!-- 設定預設啟用這個配置 -->
            <activeByDefault>true</activeByDefault>
        </activation>
    </profile>
    <profile>
        <!-- 釋出環境 -->
        <id>release</id>
        <properties>
            <profiles.active>release</profiles.active>
        </properties>
    </profile>
    <profile>
        <!-- 測試環境 -->
        <id>beta</id>
        <properties>
            <profiles.active>beta</profiles.active>
        </properties>
    </profile>
</profiles> 



<build>
    <finalName>helloworld</finalName>
    <resources>
        <!-- 先全部不包含 -->
        <resource>
            <directory>src/main/resources</directory>
            <excludes>
                <exclude>config/</exclude>
            </excludes>
        </resource>
        <!-- 再指定需要包含的資料夾 -->
        <resource>
            <directory>src/main/resources/config/${profiles.active}</directory>
            <targetPath>.</targetPath>
        </resource>
    </resources>
</build>

id代表這個環境的唯一標識,在 mvn install -Pdev 來指定。
此properties定義了三個環境,分別是dev(開發環境)、beta(測試環境)、release(釋出環境)
activeByDefault=true代表如果不指定某個固定id的profile,那麼就使用這個環境

使用mvn install -Pdev會將 id 為 dev 的 profile 中的<properties>定義的屬性profiles.active自動替換${profiles.active}佔位符的變數。最終build到classpath的資原始檔由maven-resources-plugin來指定,為src/main/resources/config/dev檔案下的所有檔案。

6.2 Spring Framework profile整合Maven profile

如果想要整合Maven profile和Spring Framework profile,Maven打包時可以對web.xml中的spring.profiles.active值進行替換。

web.xml中配置一個佔位符${profiles.active}:

<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>${profiles.active}</param-value>
</context-param>

pom.xml配置maven-war-plugin

<!-- 打war包時替換佔位符 -->
<build>
  <plugin>
    <artifactId>maven-war-plugin</artifactId>
    <version>3.2.2</version>
    <configuration>
      <!-- 過濾Deployment Descriptor並將檔案中的佔位符替換為pom.xml中對應的<properties>值 -->
      <filteringDeploymentDescriptors>true</filteringDeploymentDescriptors>
    </configuration>
  </plugin>
</build>

<!-- 預設的maven profile -->
<properties>
  <profiles.active>dev</profiles.active>
</properties>

<profiles>
  <profile>
    <id>dev</id>
    <properties>
      <profiles.active>dev</profiles.active>
    </properties>
  </profile>
  <profile>
    <id>release</id>
    <properties>
      <profiles.active>release</profiles.active>
    </properties>
  </profile>
</profiles>

以上配置完成後,再通過mvn package -Pdevmvn package -Preelase打包後,${profiles.active}<佔位符就被替換為devrelease

七、Maven 變數

1. 內建屬性

  • ${basedir}represents the directory containing pom.xml
  • **{version}** equivalent toversionequivalentto{project.version } or ${pom.version }

2. Pom/Project properties

所有pom中的元素都可以用 project. 字首進行引用,以下是部分常用的

  • **{project.build.directory}** results in the path to your "target" dir, this is the same asproject.build.directoryresultsinthepathtoyour"target"dir,thisisthesameas{pom.project.build.directory}
  • ${project.build.outputDirectory}results in the path to your "target/classes" dir
  • ${project.name}refers to the name of the project.
  • ${project.version}refers to the version of the project.
  • ${project.build.finalName}refers to the final name of the file created when the built project is packaged

3. 本地使用者設定

所有用的的 settings.xml 中的設定都可以通過 settings. 字首進行引用

  • ${settings.localRepository}refers to the path of the user's local repository.
  • ${maven.repo.local}also works for backward compatibility with maven1

4. 環境變數

系統的環境變數通過 env. 字首引用

  • ${env.M2_HOME}returns the Maven2 installation path.
  • **{java.home}** specifies the path to the current JRE_HOME environment use with relative paths to get for example: <jvm>java.homespecifiesthepathtothecurrentJREHOMEenvironmentusewithrelativepathstogetforexample:<jvm>{java.home}../bin/java.exe</jvm>

5. java系統屬性

所有JVM中定義的java系統屬性.

6. pom.xml自定義變數

<project> 
    ... 
    <properties> 
        <project.build.finalName>hellowolrld</project.build.finalName> 
    </properties> 
    ... 
</project> 

則引用 ${project.build.finalName} 就會得到值 hellowolrld

7. parent 工程的變數

parent工程的pom.xml中的變數用字首${project.parent}引用. 上級工程的版本也可以這樣引用:${parent.version }.

參考文章:
https://blog.csdn.net/wwbmyos...
https://blog.csdn.net/j080624...
http://xxgblog.com/2015/10/23...
https://blog.csdn.net/java_an...
https://blog.csdn.net/xiao__g...

轉自:https://segmentfault.com/a/1190000015077021