Maven管理依賴

    有人認爲Maven是一個依賴管理工具,當然這種想法是錯誤的(確切的說Maven是一個項目管理工具,貫穿了整個項目生命週期,編譯,測試,打 包,發佈...),但Maven給人造成這種錯誤的印象也是有原因的,因爲Maven的依賴管理十分強大,用好了Maven,你不再需要面對一大堆jar 感到頭大,依賴衝突,無用依賴等問題也能夠得到有效的防止和解決。

最簡單的依賴

    依賴是使用Maven座標來定位的,而Maven座標主要由GAV(groupId, artifactId, version)構成。因此,使用任何一個依賴之間,你都需要知道它的Maven座標。

最簡單的依賴如:

Xml代碼  收藏代碼

<dependency>  

    <groupId>junit</groupId>  

    <artifactId>junit</artifactId>  

    <version>4.4</version>  

</dependency>  

    上例中我們聲明瞭一個對junit的依賴,它的groupId是junit, artifactId是junit, version是4.4。這一組GAV構成了一個Maven座標,基於此,Maven就能在本地或者遠程倉庫中找到對應的junit-4.4.jar文件。

依賴歸類

    隨着項目的增大,你的依賴越來越多,比如說你依賴了一堆spring的jar,有org.spring.framework:spring- core, org.spring.framework:beans, org.spring.framework:spring-web, org.spring.framework:spring-mock。它們的groupId是相同的,artifactId不同。爲了管理其版本,你對它 們進行過統一的升級,逐個的將version改成了最新版。但是,顯然,當POM很大的時候你說不定會犯錯誤,而當版本不一致的時候,一些詭異的兼容性問 題就可能出現。

對此,Maven有它的解決方案:

Xml代碼  收藏代碼

<dependencies>  

    <dependency>  

        <groupId>org.spring.framework</groupId>  

        <artifactId>spring-core</artifactId>  

        <version>${spring.version}</version>  

    </dependency>  

    <dependency>  

        <groupId>org.spring.framework</groupId>  

        <artifactId>spring-beans</artifactId>  

        <version>${spring.version}</version>  

    </dependency>  

    <dependency>  

        <groupId>org.spring.framework</groupId>  

        <artifactId>spring-web</artifactId>  

        <version>${spring.version}</version>  

    </dependency>  

    <dependency>  

        <groupId>org.spring.framework</groupId>  

        <artifactId>spring-mock</artifactId>  

        <version>${spring.version}</version>  

    </dependency>  

</dependencies>  

  

<properties>  

    <spring.version>2.5</spring.version> 

</properties>  

    這裏我們定義了一個Maven屬性,其名稱爲spring.version,值是2.5。在這個POM中,我們就能 用${spring.version}的方式來引用該屬性。我們看到,所有spring相關的依賴的version元素現在都成 了${spring.version},當Maven運行的時候,它會自動用值2.5來替換這個引用。當我們需要升級spring的時候,只要更改一個地方便可,而且,你現在能很高的保證所有的spring依賴包都是同一個版本。

依賴範圍(scope)

    本文的第一個例子其實是有漏洞的,對於Junit,一般來說你只有在運行測試的時候需要它,也就是說,它對於src/main/java的classpath沒什麼意義,並且,將Junit的jar文件打入最終的發佈包也不是好事,這無謂的增加了發佈包的大小。

其實我們應該這樣做:

Xml代碼  收藏代碼

<dependency>  

    <groupId>junit</groupId>  

    <artifactId>junit</artifactId>  

    <version>4.4</version>  

    <scope>test</test>  

</dependency>  

    於是,junit對於主源碼classpath不可用,對於測試源碼classpath可用,不會被打包。

    再舉個例子,在開發javaee應用的時候我們一定會用到servlet-api,它對於主源碼和測試源碼都是必要的,因爲我們的代碼中會引入 servlet-api的包。但是,在打包的時候,將其放入WAR包就會有問題,因爲web容器會提供servlet-api,如果我們再將其打包就會造 成依賴衝突,解決方案如下:

Xml代碼  收藏代碼

<dependency>  

    <groupId>javax.servlet</groupId>  

    <artifactId>servlet-api</artifactId>  

    <version>2.4</version>  

    <scope>provided</scope>  

</dependency>  

    將依賴範圍設置成provided,就意味着該依賴對於主源碼classpath,以及測試classpath可用,但不會被打包。這正是servlet-api所需要的。

這裏歸納一下主要的依賴範圍以及作用:

 

依賴範圍(scope)主源碼classpath可用測試源碼classpath可用會被打包
compile 缺省值TRUETRUETRUE
testFALSETRUEFALSE
runtimeFALSETRUETRUE
providedTRUETRUEFALSE


需要注意的是,當我們沒有聲明依賴範圍的時候,其默認的依賴範圍是compile。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章