Maven解讀:項目依賴管理如何優化
Github地址:https://github.com/zwjlpeng/Maven_Detail
Maven最大的好處莫過于其強大的依賴管理系統,在Pom配置文件中指定項目需要的Jar包的坐標,Maven就可以自動幫我們從中央倉庫或者自已的私服下載,當項目中由于依賴的傳遞性,引入了兩份相同的Jar包時,Maven也會根據自已的規則如路徑最短,先聲明者優先對相同Jar包進行取舍,達到項目類路徑中只保留一份Jar包的目的,我們不排隊一些粗心的程序員,在同一份Pom配置文件中對相同Jar寫了兩份不同版本的依賴,就算這種情況,Maven也能完美的解決,不信你試試~~
即然Maven能夠完美的解決項目的依賴關系,那為什么我們還需要優化項目的依賴呢?原因大概如下
1.當項目依賴于某一第三方Jar包,而這一第三方Jar包又給我們間接性的帶來了大量的依賴,這種間接性的依賴,不僅浪費了磁盤空間,而且也可能帶來潛在的沖突,因此我們需要將這些不需要的依賴從項目中排除,對項目進行一個瘦身,這時我們需要對Pom進行優化,再或者,通過間接性依賴獲得的Jar包版本過低,而這些低版本的Jar包無法滿足我們項目的需求,這時我們也需要將這些低版本的Jar包排除掉,如下是一個示例:
<dependency> <groupId>net.sf.spring-json</groupId> <artifactId>spring-json</artifactId> <version>1.3.1</version> </dependency>
當我們在項目中通過Maven依賴引入spring-json時,該依賴會給我們帶來cglib-full以及低版本的spring,可以將這兩個包從項目類路徑中排除,只需要將配置更改成如下即可
<dependency> <groupId>net.sf.spring-json</groupId> <artifactId>spring-json</artifactId> <version>1.3.1</version> <exclusions> <exclusion> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> </exclusion> <exclusion> <groupId>cglib</groupId> <artifactId>cglib-full</artifactId> </exclusion> </exclusions> </dependency>
通過exclusion節點可以斷開對某一Jar包的傳遞性依賴,如果要斷開某一Jar包的所有傳遞性依賴,可以這樣配置
<dependency> <groupId>net.sf.spring-json</groupId> <artifactId>spring-json</artifactId> <version>1.3.1</version> <exclusions> <exclusion> <groupId>*</groupId> <artifactId>*</artifactId> </exclusion> </exclusions> </dependency>
2.多模塊項目中,當我們將模塊依賴的Jar分別定義在各自模塊的配置文件中,各模塊之間的依賴完全獨立,這時可能出現的情況是,模塊A與模塊B依賴的spring版本完全不同,某天,我們需要對這兩個項目的spring版本升級時,才發現我們不得不更改模塊A與模塊B兩個項目的配置文件,當模塊數目少時,我們還可以將就著!但是當模塊數多了話...,呵呵!這時我們就需要對項目的依賴進行優化,如下是一個示例,
未優化前的項目配置
模塊A
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.6.1</version> </dependency>
模塊B
<dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.4.0</version> </dependency>
模塊A與模塊B之間依賴的jedis版本完全不同,當我們需要升級時,只能一個一個的改,那為什么沒有一個統一的方式,實現在一個地方更改后,模塊A與模塊B的依賴版本均自動更改呢,有,Maven給我們提供了,這就是dependencyManagement
dependencyManagement與dependencies節點的區別
Maven已經具備了面向對象的思想,面向對象的三要素就是多態、繼承、封裝,dependencies與dependencyManagement就涉及到的是繼承的思想,在多模塊項目中,我們有一些依賴,需要在每一個模塊中都需要用到,如果在每一個模塊中我們將重復使用的依賴都寫一遍,作為一名追求完美的程序員,你能受得了嘛...,受得了的,我也只能呵呵下...,于是pom中就有了繼承的概念,在我們父模塊的Pom中,將各個子模塊都需要的依賴定義在dependencies這個節點中,子模塊中只需要繼承父模塊即可獲取該依賴,繼承的配置代碼如下:
<modelVersion>4.0.0</modelVersion> <parent> <groupId>com.test</groupId> <artifactId>ecom_airTicket</artifactId> <version>1.0</version> </parent> <artifactId>ecom_airTicket_online</artifactId> <packaging>war</packaging> <name>ecom_airTicket_online</name>
例如,多模塊項目中,各個模塊一般均需要Junit測試Jar包,因此在父Pom配置文件中,我們可以將這個依賴寫入
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> </dependencies>
這樣凡是繼承該Pom文件的均會在類路徑中加入Junit.jar包
再想想,有一些依賴,是各個子模塊所特有的,如果放在父模塊的POM中進行定義,那么所有繼承了該父模塊的子模塊均會存在該依賴,這樣的結果是啥,項目中存在大量冗余Jar包,不但浪費了磁盤,而且也不利于管理,那么就有人說,我將每個模塊各自依賴的Jar包定義在各自的Pom文件中,Good Idea!,但是再想想,假如A與B子模塊均依賴于某一個第三方Jar包,這時如果要對該第三方Jar包進行升級,就需要變更A與B兩個模塊中的POM文件,哪一天,一不小心,你只變換了A模塊,而忘了B模塊,隨后又將項目發到了線上,后果...,再試想一下,如果項目中有很多模塊依賴于同一第三方Jar包,又有誰能記得信該更改哪些呢~~
于是乎,Maven就給我們提供了dependencyManagement,在dependencyManagement節點中定義的依賴均不會被繼承,即然不會被繼承,那要它干啥?
答案是dependencyManagement可以統一管理多模塊項目中依賴的版本號,能讓我們在子項目中引用一個依賴而不用顯式的列出版本號,Maven 會沿著父子層次向上走,直到找到一個擁有dependencyManagement 元素的項目,然后它就會使用在這個dependencyManagement 元素中指定的版本號,當然如果子項目定義了一個版本,它將覆蓋頂層POM 的dependencyManagement 元素中的版本
如下是一個示例
父POM配置文件
<dependencyManagement> <!-- 配置項目依賴 --> <dependencies> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>${zookeeper.version}</version> </dependency> <dependency> <groupId>org.opensymphony.quartz</groupId> <artifactId>quartz-all</artifactId> <version>${quartz.version}</version> </dependency> <dependency> <groupId>oro</groupId> <artifactId>oro</artifactId> <version>${oro.version}</version> </dependency> </dependencyManagement>
子模塊中我們只需要這樣寫
<!-- 配置項目依賴 --> <dependencies> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> </dependency> </dependencies>
等下次我們需要升級我們的版本時,只需要在父模塊中更改,這樣不是一勞永逸嘛~~
來自:http://www.cnblogs.com/WJ5888/p/4354064.html