Maven依賴管理與命名規範

Maven作爲依賴管理工具最大的好處就是能夠方便的聲明第三方的jar包,只需要在pom中進行簡單的聲明就可以將此jar包依賴到項目中,依賴又分直接依賴和間接依賴,那什麼是直接依賴呢?就是在項目中直接聲明的依賴,間接依賴是由直接依賴間接依賴到項目的那些jar包。

排除依賴

當項目依賴於某一第三方Jar包,而這一第三方Jar包又給我們間接性的帶來了大量的依賴,這種間接性的依賴,不僅浪費了磁盤空間,而且也可能帶來潛在的衝突,因此我們需要將這些不需要的依賴從項目中排除,對項目進行一個瘦身,這時我們需要對Pom進行優化,再或者,通過間接性依賴獲得的Jar包版本過低,而這些低版本的Jar包無法滿足我們項目的需求,這時我們也需要將這些低版本的Jar包排除掉,也就是下面的exclusion標籤:

<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>
<dependency>    
<groupId>org.springframework</groupId> 
<artifactId>spring-core</artifactId> 
<version>2.5.6</version>  
<exclusions> 
  <exclusion>      
   <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId> 
          </exclusion>  
     </exclusions> 
</dependency> 

工具篩選

Maven沒有任何聲明排除jar包的情況下,默認是將全部jar包引入進來,有時候當前項目使用的jar包與依賴的第三方的jar包不同,會出現同個項目構建後出現一個jar包幾個不同版本同時存在的問題,有時會引發jar包衝突
可以通過命令或者是在IDE中查看依賴樹,排查依賴關係:

mvn dependency : list

經過Maven解析之後,就會構成一個依賴樹
也可以使用命令查看當前項目的依賴樹:

mvn dependency : tree

使用命令分析當前當前項目的依賴:

mvn dependency : analyze

該命令執行結果的兩個重要部分:
Used undeclared dependencies: 表示項目中使用到的,但是沒有顯示聲明的依賴
Unused declared dependencies: 表示項目中未使用的,但顯示聲明的依賴
該命令只會分析編譯主代碼和測試代碼需要用到的依賴,一些執行測試和運行時需要的依賴它無法發現。
ps:exclusions是在某個具體依賴裏面配置的,也就是說要找到需排除的jar包的依賴座標
以下是eclipse中的通過配置工具查看依賴、刪除依賴的位置:

打開pom.xml,選中下發Dependency Hierarchy,選中右側jar包,右鍵排除依賴就可以了。

配置可選

maven還有個可選依賴的設置,在當前項目A設置對某個依賴是可選的:

<optional>true</optional>
<dependency>
    <groupId>sample.ProjectB</groupId>
    <artifactId>Project-B</artifactId>
    <version>1.0</version>
    <scope>compile</scope>
    <optional>true</optional>
</dependency>
  這樣設置後,再有個項目X依賴A時,如果X中沒有B中的類路徑,則不會把B依賴加進來。

依賴規則

大家看到直接依賴和間接依賴之後可能會有疑問,由不同的直接依賴產生的同一jar包不同版本的jar包之間的間接依賴怎麼進行排除?這就要講到maven的規則:

  1. 第一聲明者優先(對於間接依賴)
    例如:A項目依賴B、C兩個項目,B和C又同時依賴D項目(依賴的D項目版本可能還是不同的),那就按照第一聲明者優先的規則,誰先聲明就用誰的,也就是對於間接依賴,路徑相同的情況下,第一聲明優先。
  2. 最後聲明者優先(對於同一pom中直接依賴的同一jar包的不同版本間)
    在pom中聲明瞭同一jar包的不同版本,誰聲明在後面就採用誰。
  3. 最短路徑優先(對於間接依賴)
    從名稱就可以看出對於間接依賴的jar包,誰的間接依賴的路徑短就採用誰的,例如A依賴B,B依賴D,而A依賴C,C依賴E,E依賴F,F依賴D,採用最短的依賴A->B->D的依賴版本。

dependencyManagement與dependencies

Maven已經具備了面向對象的思想,面向對象的三要素就是多態、繼承、封裝,dependencies與dependencyManagement就涉及到的是繼承的思想。
多模塊項目中,各個模塊一般均需要Junit測試Jar包,因此在父Pom配置文件中,我們可以將這個依賴寫入:

<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

此模塊的各個子模塊就可以直接繼承此jar包了。
再想想,有一些依賴,是各個子模塊所特有的,如果放在父模塊的POM中進行定義,那麼所有繼承了該父模塊的子模塊均會存在該依賴,這樣的結果是啥,項目中存在大量冗餘Jar包,不但浪費了磁盤,而且也不利於管理,所以:

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>

我們可以這樣定義jar包在父模塊,這樣子模塊就不會繼承了,如果子模塊需要用到jar包就需要重新聲明:

<!-- 配置項目依賴 -->
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
</dependencies>

可以省略版本,這樣有利於控制版本,當然也可以自己定義在子模塊中版本,這樣將採用子模塊中的版本。

命名規範

Guide to naming conventions on groupId, artifactId and version
groupId will identify your project uniquely across all projects, so we need to enforce a naming schema. It has to follow the package name rules, what means that has to be at least as a domain name you control, and you can create as many subgroups as you want. Look at More information about package names.
eg. org.apache.maven, org.apache.commons
A good way to determine the granularity of the groupId is to use the project structure. That is, if the current project is a multiple module project, it should append a new identifier to the parent's groupId.
eg. org.apache.maven, org.apache.maven.plugins, org.apache.maven.reporting
artifactId is the name of the jar without version. If you created it then you can choose whatever name you want with lowercase letters and no strange symbols. If it's a third party jar you have to take the name of the jar as it's distributed.
eg. maven, commons-math
version if you distribute it then you can choose any typical version with numbers and dots (1.0, 1.1, 1.0.1, ...). Don't use dates as they are usually associated with SNAPSHOT (nightly) builds. If it's a third party artifact, you have to use their version number whatever it is, and as strange as it can look.
eg. 2.0, 2.0.1, 1.3.1

以上內容是maven官網文檔中的,命名約定指南
總的來說:
groupId:定義當前Maven項目隸屬的實際項目,例如org.sonatype.nexus,此id前半部分org.sonatype代表此項目隸屬的組織或公司,後部分代表項目的名稱,如果此項目多模塊話開發的話就子模塊可以分爲org.sonatype.nexus.plugins和org.sonatype.nexus.utils等。特別注意的是groupId不應該對應項目隸屬的組織或公司,也就是說groupId不能只有org.sonatype而沒有nexus。
如:我建立一個項目,此項目是此後所有項目的一個總的平臺,那麼groupId應該是org.limingming.projectName,projectName是平臺的名稱,org.limingming是代表我個人的組織,如果以我所在的浪潮集團來說的話就應該是com.inspur.loushang。
artifactId是構件ID,該元素定義實際項目中的一個Maven項目或者是子模塊,如上面官方約定中所說,構建名稱必須小寫字母,沒有其他的特殊字符,推薦使用“實際項目名稱-模塊名稱”的方式定義,例如:spirng-mvn、spring-core等。
推薦格式:使用實際項目名稱作爲artifactId的前綴,緊接着爲模塊名稱
舉例:nexus-indexer、spring-mvc、hibernate-c3po……這些id都是以實際項目名稱作爲前綴,然後接着一箇中劃線,再緊跟項目的模塊名稱,默認情況下maven會在artifactId添加version作爲最後生成的名稱。例如:spirng-mvn-2.0.0.jar

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