1. 程式人生 > 其它 >mavn配置 pom.xml詳解

mavn配置 pom.xml詳解

一.標準開局

<?xmlversion="1.0"encoding="UTF-8"?>
<projectxmlns="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.0http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.tengj</groupId>
<artifactId>springBootDemo1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springBootDemo1</name>
</project>

程式碼的第一行是XML頭,指定了該xml文件的版本和編碼方式。project是所有pom.xml的根元素,它還聲明瞭一些POM相關的名稱空間及xsd元素。根元素下的第一個子元素modelVersion指定了當前的POM模型的版本,對於Maven3來說,它只能是4.0.0。

程式碼中最重要是包含了groupId,artifactId和version了。這三個元素定義了一個專案基本的座標,在Maven的世界,任何的jar、pom或者jar都是以基於這些基本的座標進行區分的。groupId定義了專案屬於哪個組,隨意命名,比如谷歌公司的myapp專案,就取名為com.google.myapp。

artifactId定義了當前Maven專案在組中唯一的ID,比如定義hello-world。

version指定了專案當前的版本0.0.1-SNAPSHOT,SNAPSHOT意為快照,說明該專案還處於開發中,是不穩定的。

name元素生命了一個對於使用者更為友好的專案名稱,雖然這不是必須的,但還是推薦為每個POM宣告name,以方便資訊交流。

二.依賴配置

<project>
...
<dependencies>
<dependency>
<groupId>實際專案</groupId>
        <artifactId>模組</artifactId>
        <version>版本</version>
        <type>依賴型別</type>
        <scope>依賴範圍</scope>
        <optional>依賴是否可選</optional>
        <!—主要用於排除傳遞性依賴-->
        <exclusions>
            <exclusion>
                <groupId>…</groupId>
                <artifactId>…</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
<dependencies>
...
</project>

根元素project下的dependencies可以包含一個或者多個dependency元素,以宣告一個或者多個專案依賴。每個依賴可以包含的元素有:
grounpId、artifactId和version:以來的基本座標,對於任何一個依賴來說,基本座標是最重要的,Maven根據座標才能找到需要的依賴。

  • type:依賴的型別,對於專案座標定義的packaging。大部分情況下,該元素不必宣告,其預設值為jar
  • scope:依賴的範圍
  • optional:標記依賴是否可選
  • exclusions:用來排除傳遞性依賴

依賴範圍

依賴範圍就是用來控制依賴和三種classpath(編譯classpath,測試classpath、執行classpath)的關係,Maven有如下幾種依賴範圍:

compile:編譯依賴範圍。如果沒有指定,就會預設使用該依賴範圍。使用此依賴範圍的Maven依賴,對於編譯、測試、執行三種classpath都有效。典型的例子是spring-code,在編譯、測試和執行的時候都需要使用該依賴。

test:測試依賴範圍。使用次依賴範圍的Maven依賴,只對於測試classpath有效,在編譯主程式碼或者執行專案的使用時將無法使用此依賴。典型的例子是Jnuit,它只有在編譯測試程式碼及執行測試的時候才需要。

provided:已提供依賴範圍。使用此依賴範圍的Maven依賴,對於編譯和測試classpath有效,但在執行時候無效。典型的例子是servlet-api,編譯和測試專案的時候需要該依賴,但在執行專案的時候,由於容器以及提供,就不需要Maven重複地引入一遍。

runtime:執行時依賴範圍。使用此依賴範圍的Maven依賴,對於測試和執行classpath有效,但在編譯主程式碼時無效。典型的例子是JDBC驅動實現,專案主程式碼的編譯只需要JDK提供的JDBC介面,只有在執行測試或者執行專案的時候才需要實現上述介面的具體JDBC驅動。

system:系統依賴範圍。該依賴與三種classpath的關係,和provided依賴範圍完全一致,但是,使用system範圍的依賴時必須通過systemPath元素顯示地指定依賴檔案的路徑。由於此類依賴不是通過Maven倉庫解析的,而且往往與本機系統繫結,可能構成構建的不可移植,因此應該謹慎使用。systemPath元素可以引用環境變數,如:

<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<Version>2.0</Version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>

import:匯入依賴範圍。該依賴範圍不會對三種classpath產生實際的影響。
上述除import以外的各種依賴範圍與三種classpath的關係如下:

傳遞性依賴

比如一個account-email專案為例,account-email有一個compile範圍的spring-code依賴,spring-code有一個compile範圍的commons-logging依賴,那麼commons-logging就會成為account-email的compile的範圍依賴,commons-logging是account-email的一個傳遞性依賴

有了傳遞性依賴機制,在使用SpringFramework的時候就不用去考慮它依賴了什麼,也不用擔心引入多餘的依賴。Maven會解析各個直接依賴的POM,將那些必要的間接依賴,以傳遞性依賴的形式引入到當前的專案中。

依賴範圍

假設A依賴於B,B依賴於C,我們說A對於B是第一直接依賴,B對於C是第二直接依賴,A對於C是傳遞性依賴。第一直接依賴和第二直接依賴的範圍決定了傳遞性依賴的範圍,如下圖所示,最左邊一行表示第一直接依賴範圍,最上面一行表示第二直接依賴範圍,中間的交叉單元格則表示傳遞依賴範圍。

從上圖中,我們可以發現這樣的規律:

  • 當第二直接依賴的範圍是compile的時候,傳遞性依賴的範圍與第一直接依賴的範圍一致;
  • 當第二直接依賴的範圍是test的時候,依賴不會得以傳遞;
  • 當第二直接依賴的範圍是provided的時候,只傳遞第一直接依賴範圍也為provided的依賴,切傳遞依賴的範圍同樣為provided;
  • 當第二直接依賴的範圍是runtime的時候,傳遞性依賴的範圍與第一直接依賴的範圍一致,但compile列外,此時傳遞性依賴範圍為runtime.

依賴調解

有時候,當傳遞性依賴造成為題的時候,就需要清楚地知道該傳遞性依賴是從哪條依賴路徑引入的。這就是依賴調解的作用,依賴調解有兩大原則:
1.路徑最近者優先
比如專案有A有這樣的依賴關係:A->B->C->X(1.0)、A->D->X(2.0),X是A的傳遞性依賴,但是兩條依賴路徑上有兩個版本的X,所以根據第一原則,A->D->X(2.0)路徑短,所以X(2.0)會被解析使用
2.第一宣告者優先
如果路徑都一樣長的話,第一原則就不行了,比如A->B->Y(1.0)、A->C->Y(2.0),Y(1.0)和Y(2.0)的路徑一樣,所以這時候根據第二原則,先宣告的被解析。

可選依賴

如圖,專案中A依賴B,B依賴於X和Y,如果所有這三個的範圍都是compile的話,那麼X和Y就是A的compile範圍的傳遞性依賴,但是如果我想X,Y不作為A的傳遞性依賴,不給他用的話。就需要下面提到的配置可選依賴。

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juvenxu.mvnbook</groupId>
<artifactId>project-b</artifactId>
<version>1.0.0</version>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.10</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</groupId>
<version>8.4-701.jdbc3</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>

配置也簡單,在依賴裡面新增

<optional>true</optional>

就表示可選依賴了,這樣A如果想用X,Y就要直接顯示的新增依賴了。

排除依賴

有時候你引入的依賴中包含你不想要的依賴包,你想引入自己想要的,這時候就要用到排除依賴了,比如下圖中spring-boot-starter-web自帶了logback這個日誌包,我想引入log4j2的,所以我先排除掉logback的依賴包,再引入想要的包就行了

排除依賴程式碼結構:

<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>

這裡注意:宣告exclustion的時候只需要groupId和artifactId,而不需要version元素,這是因為只需要groupId和artifactId就能唯一定位依賴圖中的某個依賴。

歸類依賴

有時候我們引入的很多依賴包,他們都來自同一個專案的不同模組,所以他們的版本號都一樣,這時候我們可以用屬性來統一管理版本號

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.juven.mvnbook.account</groupId>
<artifactId>accout-email</artifactId>
<version>1.0.0-SNAPSHOT</version>
<properties>
<springframework.version>1.5.6</springframework.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${springframework.version}</version>
</dependency>
</dependencies>
</project>

如圖所示,先通過

</properties>
    這裡定義你先要的版本
</properties>

來定義,然後在下面依賴使用${}來引入你的屬性。

本文版權歸作者所有,歡迎轉載,請務必新增原文連結。