Maven 實戰小結

思惟導圖

maven

Maven 與構建

什麼是 Maven

翻譯:知識的積累、專家、內行。跨平臺的項目管理工具。Apache 組織的開源項目。主要服務於基於 Java 平臺的項目構建、依賴管理和項目信息管理。php

相似於 linux 平臺的 yum、apt,前端領域的 npm。Maven 前身爲 Ant 目前 tomcat 的源碼就是用 Ant 來構建和管理,更先進的工具備 Gradle, Spring 工程在用。html

什麼是構建

何爲構建:編譯、運行單元測試、生成文檔、打包、部署的過程,這就是構建。前端

構建的步驟:java

  • 清理 clean:將之前編譯獲得的舊文件 class 字節碼文件刪除。
  • 編譯 compile:將 java 源程序編譯成 class 字節碼文件。
  • 測試 test:自動測試,自動調用 junit 程序。
  • 報告 report:測試程序執行的結果。
  • 打包 package:動態 Web 工程打 War 包,java 工程打 jar 包。
  • 安裝 install:將打包獲得的文件複製到 「倉庫」 中的指定位置(Maven特定的概念)。
  • 部署 deploy:將動態 Web 工程生成的 war 包複製到 Servlet 容器下,使其能夠運行。

項目骨架

pom:Project Object Modellinux

根目錄:工程名
|---src:源碼
|---|---main:主程序
|---|---|---java:主程序代碼路徑
|---|---|---resource:主程序配置文件路徑
|---|---test:測試
|---|---|---java:測試代碼路徑
|---|---|---resource:測試配置文件路徑
|---pom.xml:maven 配置文件
複製代碼

簡單演示

## 1. 使用 archetype 命令生成 maven 簡單骨架
mvn archetype:generate -DarchetypeCatalog=internal

## 2. 編譯當前生成的項目
mvn compile

## 3. 使用其餘命令
mvn test-compile  
mvn package  
mvn clean 
mvn install
mvn depoly 暫時不演示
複製代碼

座標與依賴

什麼是座標

類比爲數學中平面幾何,座標(x、y ),任何一個座標都能惟一標識該平面中的一個點。該點對應到 maven 就是 .jar、.war 等文件的文件。Maven 使用 groupId、artifactId、version、packaging、classifier 等元素來組成本身的座標,並定義一組這樣的規則,只要能提供正確座標元素 Maven 就能找到對應的構件。git

座標元素:github

  • groupId:定義當前 Maven 項目隸屬的實際項目。
  • artifactId:定義實際項目中的一個 Maven 項目(模塊)。
  • packaging:定義 Maven 項目打包方式。jar、war、pom。默認爲 jar。
  • version:定義 Maven 項目當前所處的版本。
  • classifier:區分從同一 artifact 構建的具備不一樣內容的構件。

classifier 使用場景算法

  • 區分基於不一樣 JDK 版本的包
<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <version>2.2.2</version>  
    <classifier>jdk13</classifier>    
    <!--<classifier>jdk15</classifier>-->
</dependency> 

複製代碼
  • 區分項目的不一樣組成部分
<dependency>  
    <groupId>net.sf.json-lib</groupId>   
    <artifactId>json-lib</artifactId>   
    <version>2.2.2</version>  
    <classifier>jdk15-javadoc</classifier>    
    <!--<classifier>jdk15-sources</classifier> -->
</dependency>
複製代碼

構件名與座標是對應的,通常規則是:artifactId-version[-classifier].packaging。spring

依賴聲明

<dependencies>
    <dependency>
        <groupId></groupId>
        <artifactId></artifactId>
        <version></version>
        <type></type>
        <optional></optional>
        <exclusions>
            <exclusion>
                <artifactId></artifactId>
                <groupId></groupId>
            </exclusion>
            ...
        </exclusions>
    </dependency>
    ...
</dependencies>
複製代碼
  • groupId、artifactId、version:依賴的基本座標。
  • type:依賴的類型,對應項目對應的 packaging,通常沒必要聲明。
  • scope:依賴的範圍,後面詳解。
  • optional:標記依賴是否可選。
  • exclusions:用來排除傳遞性依賴。

依賴範圍

  • compile:編譯依賴範圍

若是沒有指定,默認使用該依賴範圍。對於編譯、測試、運行三種 classpath 都有效。如:spring-core。sql

  • test:測試依賴範圍

只對於測試 classpath 有效,只須要在編譯測試及運行測試才須要,在打包的時候不會打進去。如:JUnit。

  • provided:已提供依賴範圍

對於編譯和測試 classpath 有效,但運行時無效。如:servlet-api 編譯和測試項目的時候都須要,但在實際運行中,容器已經提供,不須要 maven 重複的引用。

  • runtime:運行時依賴範圍

對於測試和運行的 classpath 有效,但在編譯主代碼時無效。如:JDBC 驅動的實現包。只有在執行測試或者運行項目時,才須要具體的 JDBC 驅動。

  • system:系統依賴範圍

與 provided 依賴範圍徹底一致,可是使用該範圍時必須經過 systemPath 元素顯式地指定依賴文件的路徑。因爲此類依賴不是經過 maven 倉庫解析的,並且每每與本機系統綁定,可能形成構建不可移植,所以應該謹慎使用。systemPath 元素能夠引用環境變量,如:

<dependencies>
    <dependency>
      <groupId>javax.sql</groupId>
      <artifactId>jdbc-stdxt</artifactId>
      <version>2.0</version>
      <scope>system</scope>
      <systemPath>${java.home}/lib/rt.jar</systemPath>
    </dependency>
  </dependencies>
複製代碼
  • import:導入依賴範圍

只在 dependencyManagement 標籤中生效,導入已經定義好的 pom 文件中 dependencyManagement 節點內容

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>4.3.16.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>
複製代碼

依賴機制與特性

依賴傳遞

A->B(compile):第一直接依賴
B->C(compile):第二直接依賴
A->C(compile):傳遞性依賴

當在A中配置

<dependency>  
    <groupId>com.B</groupId>  
    <artifactId>B</artifactId>  
    <version>1.0</version>  
</dependency>
複製代碼

則會自動導入 C 包。

傳遞性依賴的範圍以下圖所示:

傳遞性依賴

依賴調解

當傳遞性依賴出現問題時,可以清楚地知道該傳遞性依賴是從哪條依賴路徑中引入的。

  1. 路徑最近者優先原則
  • A->B->C->X(1.0)
  • A->D->X(2.0)

因爲只能導入一個版本的包,按照最短路徑選擇導入 X(2.0)

  1. 第一聲明者優先原則
  • A->B->Y(1.0)
  • A->C->Y(2.0)

此時因爲依賴路徑長度一致,按照第一聲明者優先原則。在路徑長度一致的前提下,若是 B 依賴在 POM 文件中聲明順序在 C 依賴以前,那麼 Y(1.0) 則會被引入。以下依賴可用於測試:

<dependencies>
    <dependency>
      <groupId>org.apache.httpcomponents</groupId>
      <artifactId>httpclient</artifactId>
      <version>4.4.1</version>
      <exclusions>
        <exclusion>
          <groupId>commons-codec</groupId>
          <artifactId>commons-codec</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>org.apache.poi</groupId>
      <artifactId>poi</artifactId>
      <version>3.9</version>
      <exclusions>
        <exclusion>
          <groupId>commons-codec</groupId>
          <artifactId>commons-codec</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

    <dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.10</version>
    </dependency>

  </dependencies>
複製代碼

這裏有一點須要特別注意,看以下依賴:

<dependencies>
    <dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.11</version>
    </dependency>

    <dependency>
      <groupId>commons-codec</groupId>
      <artifactId>commons-codec</artifactId>
      <version>1.10</version>
    </dependency>
  </dependencies>
複製代碼

按照兩原則,指望獲得的結果應該是 1.11 版本的構建將被依賴。但實際結果卻依賴了 1.10 版本。what!這不是違反了 maven 依賴調解的最早定義原則? 網友的類似疑問:stackoverflow.com/questions/4…....

其實這個是 dependency 插件的功能,默認採用的是複寫的策略,當構建聲明處於同一 pom 中,且 groupid 和 artifactId 一致時,以最新聲明爲準,後面的覆蓋前面的。注意這裏沒涉及到依賴調解的功能。個人理解是依賴調解只發生於構建來自不一樣 pom 時,而此時構建聲明處於同一 pom,故不會觸發依賴調解。

參考:maven.apache.org/plugins/mav…

可選依賴

A->B、B->X(可選)、B->Y(可選)。項目 A 依賴於項目 B,項目 B 依賴於項目 X 和 Y。理論上項目 A 中,會把 B、X、Y 項目都依賴進來。可是 X、Y 兩個依賴對於 B 來說多是互斥的,如 B 是數據庫隔離包,支持多種數據庫 MySQL、Oracle,在構建 B 項目時,須要這兩種數據庫的支持,但在使用這個工具包時,只會依賴一個數據庫。此時就須要在 B 項目 pom 文件中將 X、Y 聲明爲可選依賴,以下:

<dependency>  
    <groupId>com.X</groupId>  
    <artifactId>X</artifactId>  
    <version>1.0</version>  
    <optionnal>true</optionnal>
</dependency>

<dependency>  
    <groupId>com.Y</groupId>  
    <artifactId>Y</artifactId>  
    <version>1.0</version>  
    <optionnal>true</optionnal>
</dependency>
複製代碼

使用 optionnal 元素標識之後,只會對當前項目 B 產生影響,當其餘的項目依賴 B 項目時,這兩個依賴都不會被傳遞。項目 A 依賴於項目 B,若是實際應用數據庫是 X, 則在 A 的 pom 中就須要顯式地聲明 X 依賴。

倉庫

倉庫分類:包括本地倉庫和遠程倉庫。其中遠程倉庫包括:私服和中央倉庫。搜索構建的順序:

  1. 本地倉庫
  2. maven settings profile 中的 repository;
  3. pom.xml 中 profile 中定義的repository;
  4. pom.xml 中 repositorys (按定義順序找);
  5. maven settings mirror;
  6. central 中央倉庫;

演示:pom 中本地倉庫

生命週期與插件

Maven 的生命週期是爲了對全部構建過程進行的抽象和統一,其中包含項目的清理、初始化、編譯、測試、打包、集成測試、驗證、部署和站點生成等幾乎全部的構建步驟。

Maven 的生命週期是抽象的,自己是不作任何實際的工做。實際的任務都交給插件來完成。意味着 Maven 只在父類中定義了算法的總體結構,子類經過重寫父類的方法,來控制實際行爲(設計模式中的模板方法 Template Method)。僞代碼以下:

public abstract class AbstractBuilder {
    public void build() {
        init();
        compile();
        test();
        package();
        integrationTest();
        deploy();
    }
    
    protected abstract void init();
    protected abstract void compile();
    protected abstract void test();
    protected abstract void package();
    protected abstract void integrationTest();
    protected abstract void deploy();
}
複製代碼

三套生命週期

Maven 的生命週期並非一個總體,Maven 擁有三套相互獨立的生命週期,它們分別爲 clean、default 和 site。

  • clean 生命週期的目的是清理項目;
  • default 生命週期的目的是構建項目;
  • site 生命週期的目的是創建項目站點;

單個生命週期執行順序

每一個生命週期包含一些階段(phase),這些階段是有順序的,而且後面的階段依賴於前面的階段。以 clean 生命週期爲例,它包含的階段有 pre-clean、clean和post-clean。當調用 pre-clean 時,只有 pre-clean 階段得以執行;當調用 clean 的時候,pre-clean和clean階段會得以順序執行,以此類推。

各個生命週期之間的關係

三套生命週期自己是相互獨立的,用戶能夠僅調用 clean 生命週期的某個階段,或者僅僅調用 default 生命週期的某個階段,而不會對其餘生命週期產生任何影響。例如,當用戶調用 clean 生命週期的 clean 階段的時候,不會觸發 default 生命週期的任何階段,反之亦然。

生命週期各個階段詳解

clean
生命週期階段 描述
pre-clean 執行一些清理前須要完成的工做。
clean 清理上一次構建生成的文件。
post-clean 執行一些清理後須要完成的工做。

default

包含 23 個階段,此處只介紹重點步驟,以下表:

生命週期階段 描述
validate 檢查工程配置是否正確,完成構建過程的全部必要信息是否可以獲取到。
initialize 初始化構建狀態,例如設置屬性。
generate-sources
process-sources 處理項目資源文件,處理項目主資源文件。通常來講,是對src/main/resources目錄的內容進行變量替換等工做後,複製到項目輸出的主classpath目錄中。
generate-resources
process-resources
compile 編譯項目的主源碼。通常來講,是編譯src/main/java目錄下的Java文件至項目輸出的主classpath目錄中。
process-classes 處理編譯生成的文件,例如 Java Class 字節碼的增強和優化。
generate-test-sources
process-test-sources 處理項目測試資源文件。通常來講,是對src/test/resources目錄的內容進行變量替換等工做後,複製到項目輸出的測試classpath目錄中。
test-compile 編譯項目的測試代碼。通常來講,是編譯src/test/java目錄下的Java文件至項目輸出的測試classpath目錄中。
process-test-classes
test 使用適當的單元測試框架(例如JUnit)運行測試。
prepare-package 在真正打包以前,爲準備打包執行任何須要的操做。
package 獲取編譯後的代碼,並按照可發佈的格式進行打包,例如 JAR、WAR 或者 EAR 文件。
pre-integration-test 在集成測試執行以前,執行所需的操做。例如,設置所需的環境變量。
integration-test 處理和部署必須的工程包到集成測試可以運行的環境中。
post-integration-test 在集成測試被執行後執行必要的操做。例如,清理環境。
verify 運行檢查操做來驗證工程包是有效的,並知足質量要求。
install 安裝工程包到本地倉庫中,該倉庫能夠做爲本地其餘工程的依賴。
deploy 拷貝最終的工程包到遠程倉庫中,以共享給其餘開發人員和工程。

site

生命週期階段 描述
pre-site 執行一些在生成項目站點以前須要完成的工做。
site 生成項目站點文檔。
post-site 執行一些在生成項目站點以後須要完成的工做。
site-deploy 將生成的項目站點發布到服務器上。

插件

Maven 三套生命週期定義各個階段不作任何實際工做,實際工做都是由插件來完成的,每一個生命週期階段都是由插件的目標來完成。在 pom 文件中聲明以下(打包源碼文件插件):

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>2.1.1</version>
            <executions>
                <execution>
                    <id>attach-sources</id>
                    <phase>verify</phase>
                    <goals>
                        <goal>jar-no-fork</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
複製代碼

插件目標

一個插件有可能有多個功能、每一個功能就是一個目標。好比 maven-dependency-plugin 有十多個目標,每一個目標對應了一個功能。插件的目標爲 dependency:analyze、dependency:tree和dependency:list。通用寫法:冒號前面是插件前綴,冒號後面是插件的目標。好比 compiler:compile。

插件目標

插件綁定

插件綁定

內置綁定

爲實現快速構建,Maven 有一套內置的插件綁定。三套生命週期的插件綁定具體以下(實際上是各個生命週期階段與插件的目標的綁定)。其中 default 生命週期的構建方式會其打包類型有關、打包類型在POM中 packaging 指定。通常有 jar、war 兩種類型。下面是默認綁定插件與生命週期關係圖:

關係

自定義綁定

自定義綁定容許咱們本身掌控插件目標與生命週期的結合.以生成項目主代碼的源碼 jar 爲例。使用到的插件和它的目標爲:maven-source-plugin:jar-no-fork。將其綁定到 default 生命週期階段 verify 上(能夠任意指定三套生命週期的任意階段)。

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-source-plugin</artifactId>
            <version>2.1.1</version>
            <executions>
                <execution>
                    <id>attach-sources</id> 
                    <phase>verify</phase> <!-- 指定做用在生命週期的哪一個階段 -->
                    <goals>
                        <goal>jar-no-fork</goal> <!-- 指定執行綁定插件的哪些目標 -->
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
複製代碼

插件配置

  • 使用命令行配置

在 maven 命令中加入 -D 參數,並伴隨一個參數鍵=參數值的形式,來配置插件目標參數。如:maven-surefire-plugin 插件提供一個 maven.test.skip 參數,當值爲 true 時會跳過執行測試:

-- 對比 mvn install
mvn install –Dmaven.test.skip=true
複製代碼
  • 使用 pom 全局配置

在聲明插件的時候,對插件進行一個全局配置,後面全部使用該插件的都要遵循這個配置。好比指定 maven-compile-plugin 編譯 1.7 版本的源文件:

<plugin>
   <groupId>org.apache.maven.plugins</groupId>
   <artifactId>maven-compiler-plugin</artifactId>
   <configuration>
       <fork>true</fork>
       <source>1.7</source>
       <target>1.7</target>
   </configuration>
</plugin>
複製代碼
  • 獲取插件信息

官方網站

maven.apache.org/plugins/ind…
maven.apache.org/plugins-arc…

命令行獲取

  • 使用 maven-help-plugin 插件
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-compiler-plugin

mvn help:describe -Dplugin=compiler

mvn help:describe -Dplugin=compiler -Dgoal=compile

mvn help:describe -Dplugin=compiler -Ddetail
複製代碼
  • 使用插件內置 help 目標
mvn compiler:help -Ddetail=true -Dgoal=compile
複製代碼
  • 插件前綴

若是插件的名稱命名爲 {prefix}-maven-plugin 或者 maven-{prefix}-plugin 這樣的格式的話,能夠直接用 mvn prefix:goal 調用。

如何查看插件的前綴:${MAVEN_HOME}\org\apache\maven\plugins\maven-metadata-central.xml

聚合與繼承

聚合:爲了一次構建多個項目模塊,就須要對多個項目模塊進行聚合

<modules>
    <module>模塊一</module>
    <module>模塊二</module>
    <module>模塊三</module>
</modules>
複製代碼

繼承:爲了消除重複,把不少相同的配置提取出來,例如:dependency、grouptId,version 等

<parent>  
    <groupId>com.xxxx.maven</groupId>
    <artifactId>parent-project</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <relativePath>../ParentProject/pom.xml</relativePath>  
</parent>
複製代碼

如下的元素是能夠被繼承的:

groupId,項目組ID;
version,項目版本;
description,項目描述信息;
organazation,項目的組織信息;
inceptionYear,項目的創始年份;
developers,項目開發者信息;
contributors,項目的貢獻者信息;
distributionManagement,項目的部署信息;
issueManagement,項目的缺陷跟蹤系統信息;
ciManagement,項目的持續集成系統信息;
scm,項目的版本控制系統信息;
mailingLists,項目的郵件列表信息;
properties,自定義的Maven屬性;
dependencies,項目的依賴配置;
dependencyManagement,項目的依賴管理配置;
repositories,項目的倉庫配置;
build,包括項目的源碼目錄配置、輸出目錄配置、插件配置、插件管理配置等;
reporting,包括項目的報告輸出目錄配置、報告插件配置。

注意下面的元素,這些都是不能被繼承的。

  • artifactId
  • name
  • prerequisites

聚合與繼承之間的關係:

  • 二者共同點爲,打方式必須都是 pom
  • 在實際的項目中,一個 pom 既是聚合 pom 又是父 pom

注: 父 pom 中使用 dependencies 引入的依賴也會被子 pom 繼承,因此不要將過多的實際依賴放在父 pom,父 pom 只用於管理,使用 dependencyManagement 標籤。(組員在這踩過坑)

靈活構建

使用屬性、 resources 插件資源過濾功能(filter)和 Maven 的 profile 功能,實現環境的靈活切換

屬性

maven.apache.org/pom.html#Pr…

經過 properties 元素用戶能夠自定義一個或者多個 Maven 屬性,而後在 pom 其餘的地方使用 ${屬性名} 的方式引用該屬性,這種方式最大意義在於消除重複。

1. 內置屬性

  • ${basedir} 表示項目根目錄,即包含 pom.xml 文件的目錄
  • ${version} 等同於 ${project.version} 或者 ${pom.version} 表示項目版本

2. POM 屬性

全部 pom 中的元素均可以用 project. 例如 ${project.artifactId} 對應了 < project><artifactId> 元素的值。經常使用的 POM 屬性包括:

${project.build.sourceDirectory} : 項目的主源碼目錄,默認爲 src/main/java/.
${project.build.testSourceDirectory} : 項目的測試源碼目錄,默認爲 /src/test/java/.
${project.build.directory} : 項目構建輸出目錄,默認爲 target/.
${project.build.outputDirectory} : 項目主代碼編譯輸出目錄,默認爲 target/classes/.
${project.build.testOutputDirectory} : 項目測試代碼編譯輸出目錄,默認爲 target/testclasses/.
${project.groupId}: 項目的 groupId.
${project.artifactId} : 項目的 artifactId.
${project.version} : 項目的 version, 等同於 ${version} ${project.build.finalName} : 項目打包輸出文件的名稱,默認爲 ${project.artifactId}${project.version}

3. 自定義屬性

在 pom 中 <properties> 元素下自定義的 Maven 屬性

<properties>
    <swagger.version>2.2.2</swagger.version>
</properties>
<dependency>
    <groupId>io.springfox</groupId>
    <artifactId>springfox-swagger2</artifactId>
    <version>${swagger.version}</version>
</dependency>
複製代碼

4. Settings 屬性

全部用的的 settings.xml 中的設定均可以經過 settings. 前綴進行引用與 POM 屬性同理。如 ${settings.localRepository} 指向用戶本地倉庫的地址

5. Java 系統屬性

全部 Java 系統屬性均可以使用 Maven 屬性引用,例如 ${user.home} 指向了用戶目錄。 能夠經過命令行 mvn help:system 查看全部的 Java 系統屬性

6. 環境變量屬性

全部環境變量均可以使用以 env. 開頭的 Maven 屬性引用。例如 ${env.JAVA_HOME} 指代了 JAVA_HOME 環境變量的值。也能夠經過命令行 mvn help:system 查看全部環境變量。

7. 父級工程屬性

上級工程的 pom 中的變量用前綴 ${project.parent} 引用. 上級工程的版本也能夠這樣引用: ${parent.version}

注:如何讀取外部 property 文件?
Properties Maven Plugin,github.com/mojohaus/pr…

fileter

maven.apache.org/plugins/mav…

Maven 的 properties filter 功能能夠幫你自動替換配置文件中以 ${}包裹的變量。爲了方便構建不一樣的環境,咱們一般將不一樣的配置以 properties 形式配置在 pom 中。 默認狀況下,Maven屬性只有在POM中才會被解析。資源過濾就是指讓 Maven 屬性在資源文件(src/main/resourcessrc/test/resources) 中也能被解析。開啓資源過濾:

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>
複製代碼

Profile

maven.apache.org/guides/intr…

profile 特性可讓咱們定義多個 profile,而後每一個 profile 對應不一樣的激活條件和配置信息,從而達到不一樣環境使用不一樣配置信息的效果。profile 能夠在如下幾個地方聲明:

  1. pom.xml:這裏聲明的 profile 只對當前項目有效
  2. 用戶 settings.xml:.m2/settings.xml 中的 profile 對該用戶的 Maven 項目有效
  3. 全局 settings.xml:conf/settings.xml,對本機上全部 Maven 項目有效

示例:

<project>
    ...
    <profiles>
      <profile>
        <id>dev</id>
        <properties>
            <active.profile>dev</active.profile>
            <key1>value1</key1>
            <key2>value2</key2>
        </properties>

        <!-- 默認激活配置 -->
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <!-- 在該 profile 下才會引入的依賴 -->
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>3.2.4.RELEASE</version>
            </dependency>
        <dependencies>
        <!-- 在該 profile 下才會加載的變量文件 -->
        <build>
            <filters>
                <filter>../profile/test-pre.properties</filter>
            </filters>
        </build>
            
      </profile>
    </profiles>
    ...
</project>
複製代碼

profile 中能夠生效的標籤

> <repositories>  
> <pluginRepositories>  
> <dependencies>  
> <plugins>  
> <properties> (not actually available in the main POM, but used behind the scenes)  
> <modules>  
> <reporting>  
> <dependencyManagement>  
> <distributionManagement>  
> a subset of the <build> element, which consists of:  
    > <defaultGoal>  
    > <resources>  
    > <testResources>  
    > <finalName>  
複製代碼

高級特性

  • 使用 SNAPSHOT 來管理未正式發佈的構件

當使用 SNAPSHOT(快照版本)管理構件版本時,每次都會去遠程倉庫上最新的依賴。

SNAPSHOT 應用場景描述:

  • 不須要發佈到遠程倉庫的包,好比一個服務的提供者,一個實現。
  • 須要發佈到遠程倉庫的包,但進度還處於開發階段,隨時可能發生變化

在 version 後面加上 "-SNAPSHOT",自動部署到遠程倉庫中的 SNAPSHOT 對應目錄下。

  • 裁剪反應堆,聚合項目打包指定個別模塊打包

裁剪反應堆應用場景描述: 一個聚合工程中包含了三個主應用(如:網關服務、服務提供者、助手項目),結構大體以下:

-- 工程主目錄
------ gateway 項目(可運行)
------ provider 項目(可運行)
------ assist 項目(可運行)
------ api 項目(被依賴)
------ common 項目(被依賴)
------ pom.xml
複製代碼

當在主目錄下執行 mvn package 後,會把 gateway、provider、assist 項目都打出包來,此時若是須要單獨打三個項目時,就須要用到裁剪反應堆。若想單獨打包 provider 項目則可以使用以下命令:

mvn package -pl provider -am
複製代碼

若想同時打包 gateway、assist 則使用以下命令:

mvn package -pl gateway,assist -am
複製代碼

反應堆詳細參數 mvn -h

-am --also-make 同時構建所列模塊的依賴模塊;
-amd -also-make-dependents 同時構建依賴於所列模塊的模塊;
-pl --projects 構建制定的模塊,模塊間用逗號分隔;
-rf -resume-from 從指定的模塊恢復反應堆。

實用插件

  • 使用 versions 插件批量修改父 pom 版本號

-- https://blog.csdn.net/GGBomb2/article/details/78316068
-- 在頂級 pom 目錄中設置版本號。
- 注:在 windows 下的 powershell 中 1.1.3-RELEASE 得加雙引號
- 注:CMD 不用加
mvn versions:set -DnewVersion=1.1.3-RELEASE
-- 設置不正確時能夠撤銷新版本號的設置
mvn versions:revert
-- 確認新版本號無誤後提交新版本號的設置
mvn versions:commit
複製代碼
  • 使用 dependency 插件分析項目內的依賴

mvn dependency:analyze

# 只想看依賴樹中包含 groupId 爲 javax.serlet 的枝幹
mvn dependency:tree -Dincludes=javax.servlet
# 不想看依賴樹中包含 groupId 爲 javax.serlet 的枝幹
mvn dependency:tree -Dexcludes=javax.servlet
複製代碼

參數的格式(pattern)定義以下:

[groupId]:[artifactId]:[type]:[version]

每一個部分(冒號分割的部分)是支持 * 通配符的,若是要指定多個格式則能夠用 , 分割,如:

mvn dependency:tree -Dincludes=javax.servlet,org.apache.*
複製代碼
  • 使用 deploy 插件進行多模塊項目區別發佈(部分須要發佈,部分不須要)

<properties>
    <maven.deploy.skip>true</maven.deploy.skip>
</properties>
複製代碼
  • 使用 shade 插件作配置文件合併等工做

my.oschina.net/u/2377110/b…

  • 使用 assembly 插件作聚合項目的輸出

my.oschina.net/u/2377110/b…

項目啓發

  1. 從 Maven 插件的設計上,體現了模板的方法的設計思想,是否是能夠用在咱們的項目上?

備忘

  • 打包語句
mvn clean install -Ptest -Dmaven.test.skip=true  -X -DskipTests package
複製代碼
  • setting 文件
<?xml version="1.0" encoding="utf-8"?>

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

    <!-- localRepository Default: ~/.m2/repository -->
    <localRepository>本地 maven 倉庫地址</localRepository>

    <pluginGroups>
        <pluginGroup>org.codehaus.cargo</pluginGroup>
        <pluginGroup>org.apache.maven.plugins</pluginGroup>
        <pluginGroup>org.codehaus.mojo</pluginGroup>
    </pluginGroups>

    <proxies>
    </proxies>

    <!-- 當須要上傳構建才須要進行身份認證 -->
    <!--<servers> <server> <id>xxx_release</id> <username></username> <password></password> </server> <server> <id>xxx_snapshots</id> <username></username> <password></password> </server> </servers>-->
        
    <!-- 設置私服才須要放開這段配置 -->
    <!-- <profiles> <profile> <id>nexus</id> <repositories> <repository> <id>倉庫id</id> <url>私服地址</url> <releases> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>warn</checksumPolicy> </releases> <snapshots> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>warn</checksumPolicy> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>倉庫id</id> <url>私服地址</url> <releases> <enabled>true</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>warn</checksumPolicy> </releases> <snapshots> <enabled>false</enabled> <updatePolicy>always</updatePolicy> <checksumPolicy>warn</checksumPolicy> </snapshots> </pluginRepository> </pluginRepositories> </profile> </profiles> <activeProfiles> <activeProfile>nexus</activeProfile> </activeProfiles> -->

    <!-- 使用阿里雲 maven 鏡像倉庫 -->
    <mirrors>
        <mirror>
            <id>alimaven</id>
            <name>aliyun maven</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public/</url>
            <mirrorOf>central</mirrorOf>
        </mirror>
    </mirrors>
</settings>
複製代碼

遇到的問題

參考資料:

相關文章
相關標籤/搜索