天天看點

maven clean/install/build/package指令行詳解(下)依賴、聚合和繼承Maven 屬性Maven 3 特性總結

依賴、聚合和繼承

依賴

我們項目中依賴的 Jar 包可以通過依賴的方式引入,通過在 dependencies 元素下添加 dependency 子元素,可以聲明一個或多個依賴。通過控制依賴的範圍,可以指定該依賴在什麼階段有效。Maven 的幾種依賴範圍:

maven clean/install/build/package指令行詳解(下)依賴、聚合和繼承Maven 屬性Maven 3 特性總結

傳遞依賴

依賴具有傳遞性,例如 Project A 依賴于 Project B,B 依賴于 C,則 B 對 C 的依賴關系也會傳遞給 A。

如果我們的項目引用了一個jar包,而該jar包又引用了其他jar包。那麼,

在預設情況下,項目編譯時, Maven會把直接引用和間接引用的jar包都

下載下傳到本地( ~/.m2/repository )。

如果我們不需要這種傳遞性依賴,可用 <optional> 去除這種依賴的傳遞,如

<dependency> 
<groupId>commons-logging</groupId> 
<artifactId>commons-logging</artifactId> 
<version>1.1.1</version> 
<optional>true<optional> 
</dependency>
      

假設第三方的 jar 包中沒有使用 

<optional>

 來去除某些依賴的傳遞性,那麼可以在目前的 POM 檔案中使用 

<exclusions>

 元素聲明排除依賴,exclusions 可以包含一個或者多個 exclusion 子元素,是以可以排除一個或者多個傳遞性依賴。如

<dependency>    
     <groupId>org.springframework</groupId>  
     <artifactId>spring-core</artifactId>  
     <exclusions>  
           <exclusion>      
                <groupId>commons-logging</groupId>          
                <artifactId>commons-logging</artifactId>  
           </exclusion>  
     </exclusions>  
</dependency>
      

依賴沖突

若項目中多個jar同時引用了相同的jar時,會産生依賴沖突,但Maven采用了兩種

避免沖突的政策,是以在Maven中是不存在依賴沖突:

  • 短路優先

    本項目 =》 A.jar =》B.jar =》 X.jar

    本項目=》 C.jar =》 Xjar

  • 聲明優先

    若引用路徑長度相同時,在pom.xmI中誰先被聲明,就使用誰

多子產品項目 / 聚合

現實中一個項目往往是由多個 project 構成的,在進行建構時,我們當然不想針對多個 project 分别執行多次建構指令,這樣極容易産生遺漏也會大大降低效率。Maven 的聚合功能可以通過一個父子產品将所有的要構模組化塊整合起來。

➢ 父子產品pom檔案的配置: packaging 類型必須是pom

<groupId>com.java.ad</ groupId>
<artifactId>java-ad</artifactId>
<packaging>pom</ packaging>
<version>1.O-SNAPSHOT</version>
      

➢聚合子子產品:使用modules标簽

<modules>
<module>ad-eureka</module>
<module>java-ad-service</module>
<module>ad-gateway</module>
</modules>
      

将父子產品的打包類型聲明為 POM,通過 

<modules>

 将各子產品集中到父 POM 中。如下其中 

<module></module>

 中間的内容為子子產品工程名的相對路徑。

maven clean/install/build/package指令行詳解(下)依賴、聚合和繼承Maven 屬性Maven 3 特性總結
  • 聚合
<modules>    
<module>../com.dugeng.project1</module> 
<module>../com.dugeng.project2</module> 
 </modules>      

父類型的子產品,不需要有源代碼和資源檔案,也就是說,沒有 src/main/java 和 src/test/java 目錄。Maven 會首先解析聚合子產品的 POM 檔案,分析要建構的子產品,并通過各子產品的依賴關系計算出子產品的執行順序,根據這個潛在的關系依次構模組化塊。将各子子產品聚合到父子產品中後,我們就可以對父子產品進行一次建構指令來完成全部子產品的建構。

繼承

在面向對象的程式設計中我們學會了繼承的概念,繼承是可重用行即消除重複編碼的行為。Maven 中繼承的用意和面向對象程式設計中是一緻的。與聚合的實作類似,我們通過建構父子產品将子子產品共用的依賴,插件等進行統一聲明,在聚合和繼承同時使用時,我們可以用同一個父子產品來完成這兩個功能。

例如将 com.dugeng.parent 這個子產品聲明為 project1 和 project2 的父子產品,那麼我們在 project1 和 2 中用如下代碼聲明父子關系,如

<parent> 
 <groupId>com.dugeng.mavenproject</groupId> 
 <artifactId>com.dugeng.parent</artifactId> 
 <version>0.0.1-SNAPSHOT</version> 
 <relativePath>../com.dugeng.parent/pom.xml</relativePath> 
</parent>
      

由于父子產品隻是用來聲明一些可共用的配置和插件資訊,是以它也像聚合子產品一樣隻需要包括一個 POM 檔案,其它的項目檔案如 src/main/java 是不需要的。

聚合和繼承存在一些共性和潛在的聯系,在實際的應用中,經常将聚合子產品的父子產品和繼承的父子產品定義為同一個。

并不是所有的 POM 元素都可以被繼承,如下是可繼承的元素清單。

可繼承元素清單

名稱 描述

groupId 項目組 ID

version 項目版本

description 描述資訊

organization 組織資訊

inceptionYear 創始年份

url 項目的 url 位址

developers 開發者

contributors 貢獻者資訊

distributionManagerment 部署資訊

issueManagement 缺陷跟蹤系統

ciManagement 持續繼承資訊

scm 版本控制資訊

mailingList 郵件清單資訊

properties 自定義的屬性

dependencies 依賴配置

dependencyManagement 依賴管理配置

repositories 倉庫配置

build 源碼目錄,插件管理等配置

reporting 報告配置

排除依賴

如果我們隻想下載下傳直接引用的jar包,那麼需要在pom.xml 中做如下配置(給出需要排除的坐标)

maven clean/install/build/package指令行詳解(下)依賴、聚合和繼承Maven 屬性Maven 3 特性總結

Maven 屬性

在 POM 檔案中常常需要引用已定義的屬性以降低代碼的備援,提高代碼的可重用性,這樣不僅能降低代碼更新的工作量也能提高代碼的正确率。有些屬性是使用者自定義的,有些屬性是可以直接引用的已定義變量。

Maven 的可用屬性類型可分為 5 種,它們分别是:

内置屬性。這種屬性跟 Maven Project 自身有關,比如要引入目前 Project 的版本信 息,那麼隻需要在使用的位置引用 ${version} 就行了。

Setting 屬性。上文中已經提到 Maven 自身有一個 settings.xml 配置檔案,它裡面含有包括倉庫,代理伺服器等一些配置資訊,利用 ${settings.somename} 就可以得到檔案裡相應元素的值。

POM 屬性。這種屬性對應 POM 檔案中對應元素的值,例如 p r o j e c t . g r o u p I d 對 應 了 < g r o u p I d > < / g r o u p I d > 中 的 值 , {project.groupId} 對應了 <groupId></groupId> 中的值,project.groupId對應了<groupId></groupId>中的值,{project.artifactId} 對應了 </ artifactId > 中的值。

系統環境變量。可以使用 env.${name} 來獲得相應 name 對應的環境變量的值,例如 ${env.JAVA_HOME} 得到的就是 JAVA_HOME 的環境變量值。

使用者自定義變量。這種類型的變量是使用最頻繁和廣泛的變量,完全由使用者自己定義。在 POM 檔案中加入 元素并将自定義屬性作為其子元素。格式如

<properties>
  <path>../../sourcecode</path>
</properties>
      

Maven 3 特性

Maven 3 在性能和靈活性方面都比 Maven2 有了很大提升,它的新特性總結起來有以下幾點:

相容低版本 Maven,也就是向後相容,是以使用者可以将 Maven2 的項目移植到 Maven3 上來。

性能優化。CPU 使用率更高,記憶體消耗更小,經過優化的 Maven3 比 Maven2 建構速度快出 50% 以上,這對于建構大型項目的開發者來說無疑會節省大量的時間。

在早先的版本中,開發者必須在子子產品中指定父版本,當進行代碼的遷移或更新時,這會帶來額外的維護工作,Maven3.1 将會消除在子子產品上指定父版本的需要。

4.Maven3 改善了錯誤報告,它會在錯誤報告中提供指向 Maven Wiki 頁面的連結,這樣開發者可以友善的檢視更全面的錯誤描述和可能的原因。

增加了 Maven Shell,通常我們可以在系統自帶的 console 裡執行 Maven 指令,但是通過自安裝的 Maven Shell 可以提高生成速度,它是一個是 Maven 的指令行接口工具,可以緩存解析過的 POM,避免了重複調用 Maven 的啟動成本。Maven Shell 不屬于 Maven 發行包的一部分,需要單獨下載下傳。

M2Eclipse 實作了 Maven 和 Eclipse 的內建,與一個使用更廣泛的 IDE 進行內建進而為開發者帶來的便利是不言而喻的。

總結

Maven 有着許多實用的特點,它使用了标準的目錄結構和部署。這就使得開發人員能夠适應不同的項目,并且不用學習任何結構方面新的東西,也不用掌握特殊的指令來建構結構。當然,Maven 的使用還不夠普及,相信随着時間的推移,它的功能會更完善,使用的人群也會越來越廣泛。