1、題記
最近剛完成一個用Maven構建的Web項目,看了一些Maven方面的書,比如《maven實戰》,但還是對Maven多模塊項目理解得不清晰,所以花了一點時間好好研究了下,現分享如下。
2、問題
下面是一個簡略的項目結構圖:
--Parent
---- childA(BusinessLayer)
`--- pom.xml`
---- childB(WebLayer)
`--- pom.xml
------ pom.xml
2.1、Parent怎麼能找到childA和childB呢?
在maven中,parent模塊組織好childA和childB,叫做"聚合",多個模塊聯合編譯。實現起來很簡單,只需要在parent的pom文件里加入以下內容。
<modules>
<module>childA</module>
<module>childB</module>
</modules>
2.2、是不是這樣寫就完全ok了?
這樣只是告訴maven編譯器,在讀取parent的pom文件時去找到childA和childB,但還是會分別去編譯他們引入的依賴。這樣就會導致pom文件引入的包重複!!於是我們引入了"繼承"的概念,也就是形成"父子"關係,子pom可以引用到父pom中引入的依賴。具體做法如下:
在parent中,寫入以下內容,其中"*"標識的行可以組成一個路徑,通過這個路徑可以在maven倉庫中找到這個pom文件!本例中,path爲M2_Path/com/sang/main/Parent-Moduel/1.0.2/xxxx-1.0.2.pom
。所以這三個標籤是必須的!!!
<modelVersion>4.0.0</modelVersion>
<groupId>com.sang.main</groupId> *
<artifactId>Parent-Moduel</artifactId> *
<version>1.0.2</version> *
<packaging>pom</packaging>
<name>Simple-main</name>
父pom寫好了,子pom就通過標籤繼承父pom的依賴,如下:
<parent>
<groupId>com.sang.main</groupId>
<artifactId>Parent-Moduel</artifactId>
<version>1.0.2</version>
<relativePath>../pom.xml</relativePath> <!--本例中此處是可選的-->
</parent>
值得注意的是<relativePath>
標籤,如果pom的層次關係就像本例中的那樣只隔一層,則可以省略這個。maven同樣可以找到子pom。
子pom中引入<parent>
標籤後,就會從父pom繼承<version>
等屬性了,例如childA只需要再加入如下內容即可!
<modelVersion>4.0.0</modelVersion>
<groupId>com.sang.business</groupId> <!--和artifactId一起唯一標識這個jar文件-->
<artifactId>ChildA-module</artifactId>
<packaging>jar</packaging> <!--指明打包類型-->
<name>childA</name>
2.3、如何添加依賴?
maven可以讓我們方便地管理jar包依賴,具體做法如下:
<dependencies>
<dependency> <!--添加一個jar包依賴-->
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
如果不通過繼承,則需要在每個pom中加入這樣的依賴,這樣子pom對應的模塊可以引用到這個jar包。上面提到的重複引用jar包,可以通過下面的方式解決:
主pom中把依賴通過<dependecyManagement>
引起來,表示子pom可能會用到的jar包依賴
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
</dependencies>
</dependencyManagement>
子pom如果需要引用該jar包,則直接引用即可!不需要加入<version>
,便於統一管理。此外也可以加入僅在子pom中用到的jar包,比如:
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId> <!--此處不再需要verison了!-->
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-lgpl</artifactId>
<version>1.9.4</version> <!--當然也可以加入只在這個子模塊中用到的jar包-->
</dependency>
</dependencies>
2.4、除了jar包依賴,插件也可以通過這樣的方式進行管理
<!-- mainModule -->
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<!-- childA -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
</plugin>
</plugins>
</build>
2.5、如果子pom間存在引用關係,比如childA引用到了childB的jar包,該怎麼做?
<dependency>
<groupId>com.module</groupId>
<artifactId>childA</artifactId> <!--加上childA的依賴-->
<version>1.0.0</version>
</dependency>
3、小結
本文只是從多模塊組織的角度說明了maven的基本用法, 當然,其他的複雜用法還是要參考maven手冊。