前言
項目中用到了maven,而且用到的内容不像利用maven/eclipse搭建ssm(spring+spring mvc+mybatis)用的那麼簡單
maven的核心是 pom.xml,那麼我們就來看看那些不同的地方
給我印象最深的就是如下四個元素:modules、parent、properties、import
modules
從字面意思來說,module 就是子產品,而 pom.xml 中的 modules 也正是這個意思,用來管理同個項目中的各個子產品
如果 maven 用的比較簡單,或者說項目的子產品在 pom.xml 沒進行劃分,那麼此元素是用不到的
稍微複雜一點的項目都是要用到的
需求場景
如果我們的項目分成了好幾個子產品,那麼我們建構的時候是不是有幾個子產品就需要建構幾次了(到每個子產品的目錄下執行 mvn 指令)?
當然,你逐個建構沒問題,但是非要這麼麻煩的一個一個的建構嗎
簡單的做法就是使用聚合,一次建構全部子產品
具體實作
既然使用聚合,那麼就需要一個聚合的載體,先建立一個普通的 maven 項目 account-aggregator,如下圖:
因為是個聚合體,僅僅負責聚合其他子產品,那麼就隻需要上述目錄,該删除的就删了
注意 pom.xml 中的紅色部分
<project xmlns="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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.youzhibing.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Aggrregator</name>
<url>http://maven.apache.org</url>
<modules>
<!-- 子產品都寫在此處 -->
<module>account-register</module>
<module>account-persist</module>
</modules>
</project>
建立子模 account-register、account-persist
右擊 account-aggregator,new --> other --> Maven,選擇 Maven Module,建立 moven 子產品
建立完成後,項目結構如下,那麼此時 account-aggregator 可以收縮起來了,我們操作具體子子產品就好了

當我們打開包結構的子子產品的 pom.xml 時,發現比預期的多了一些内容,我們做下處理就好了
那麼編碼完了之後,我們隻需要建構 account-aggregator 就好了,所有的子子產品都會建構
parent
繼承,和 java 中的繼承相當,作用就是複用
若每個子子產品都都用的了 spring,那麼我們是不是每個子子產品都需要單獨配置 spring依賴了?
這麼做是可以的,但是我們有更優的做法,那就是繼承,用 parent 來實作
配置父 pom.xml
我們就用聚合pom來做父pom,配置子子產品的公共依賴
父(account-aggregator) pom.xml
<project xmlns="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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.youzhibing.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Aggrregator</name>
<url>http://maven.apache.org</url>
<modules>
<!-- 子產品都寫在此處 -->
<module>account-register</module>
<module>account-persist</module>
</modules>
<dependencies> <!-- 配置共有依賴 -->
<!-- spring 依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<!-- junit 依賴 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
View Code
account-register 的 pom.xml
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.youzhibing.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <!-- 與不配置一樣,預設就是尋找上級目錄下得pom.xml -->
</parent>
<artifactId>account-register</artifactId>
<name>account-register</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies> <!-- 配置自己獨有依賴 -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>com.icegreen</groupId>
<artifactId>greenmail</artifactId>
<version>1.4.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
account-persist 的 pom.xml
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.youzhibing.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>account-persist</artifactId>
<name>account-persist</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies> <!-- 配置自己獨有依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.16</version>
</dependency>
</dependencies>
</project>
依賴的 jar 包全部 ok,需要做的則是在各個子產品中進行代碼開發了!
依賴管理
繼承可以消除重複,那是不是就沒有問題了? 還是有小瑕疵的
假設将來需要添加一個新的子子產品account-util,該子產品隻是提供一些簡單的幫助工具,不需要依賴spring、junit,那麼繼承後就依賴上了,有沒有什麼辦法了?
有,maven已經替我們想到了,那就是 dependencyManagement 元素,既能讓子子產品繼承到父子產品的依賴配置,又能保證子子產品依賴使用的靈活性
在 dependencyManagement 元素下得依賴聲明不會引入實際的依賴,不過它能夠限制 dependencies 下的依賴使用
在父 pom.xml 中配置 dependencyManagement 元素
<project xmlns="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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.youzhibing.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Aggrregator</name>
<url>http://maven.apache.org</url>
<modules>
<!-- 子產品都寫在此處 -->
<module>account-register</module>
<module>account-persist</module>
</modules>
<dependencyManagement>
<dependencies> <!-- 配置共有依賴 -->
<!-- spring 依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<!-- junit 依賴 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
account-persist的pom.xml(account-register也一樣) :
<?xml version="1.0"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.youzhibing.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>account-persist</artifactId>
<name>account-persist</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- spring 依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<!-- junit 依賴 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.0.2.RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.16</version>
</dependency>
</dependencies>
</project>
使用這種依賴管理機制似乎不能減少太多的POM配置,就少了version(junit還少了個scope),感覺沒啥作用呀
其實作用還是挺大的,父 pom.xml 使用 dependencyManagement 能夠統一項目範圍中依賴的版本
當依賴版本在父POM中聲明後,子子產品在使用依賴的時候就無須聲明版本,也就不會發生多個子子產品使用版本不一緻的情況,幫助降低依賴沖突的幾率
如果子子產品不聲明依賴的使用,即使該依賴在父 pom.xml 中的 dependencyManagement 中聲明了,也不會産生任何效果
import
import 隻在 dependencyManagement 元素下才有效果,作用是将目标 pom.xml 中的 dependencyManagement 配置導入并合并到目前 pom.xml 的 dependencyManagement 元素中
如下就是講 account-aggregator中 的 dependencyManagement 配置導入并合并到目前 pom.xml 中
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.youzhibing.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
properties
通過 properties 元素使用者可以自定義一個或多個 maven 屬性,然後在 pom.xml 的其他地方使用 ${屬性名} 的方式引用該屬性,這種做法的最大意義在于消除重複和統一管理
maven 總共有 6 類屬性,内置屬性、POM屬性、自定義屬性、Settings屬性、java系統屬性和環境變量屬性
内置屬性
兩個常用内置屬性 ${basedir} 表示項目跟目錄,即包含 pom.xml 檔案的目錄;${version} 表示項目版本
pom 屬性
使用者可以使用該類屬性引用POM檔案中對應元素的值。如${project.artifactId}就對應了<project> <artifactId>元素的值,常用的POM屬性包括:
${project.build.sourceDirectory}:項目的主源碼目錄,預設為src/main/java/
${project.build.testSourceDirectory}:項目的測試源碼目錄,預設為src/test/java/
${project.build.directory} : 項目建構輸出目錄,預設為target/
${project.outputDirectory} : 項目主代碼編譯輸出目錄,預設為target/classes/
${project.testOutputDirectory}:項目測試主代碼輸出目錄,預設為target/testclasses/
${project.groupId}:項目的groupId
${project.artifactId}:項目的artifactId
${project.version}:項目的version,與${version} 等價
${project.build.finalName}:項目打包輸出檔案的名稱,預設為${project.artifactId}-${project.version}
自定義屬性
如下 account-aggregator 的 pom.xml,那麼繼承了此 pom.xml 的子子產品也可以用此自定義屬性
<project xmlns="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.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.youzhibing.account</groupId>
<artifactId>account-aggregator</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Account Aggrregator</name>
<url>http://maven.apache.org</url>
<modules>
<!-- 子產品都寫在此處 -->
<module>account-register</module>
<module>account-persist</module>
<module>account-another</module>
</modules>
<properties>
<!-- 定義 spring版本号 -->
<spring.version>4.0.2.RELEASE</spring.version>
<junit.version>4.7</junit.version>
</properties>
<dependencyManagement>
<dependencies> <!-- 配置共有依賴 -->
<!-- spring 依賴 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- junit 依賴 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
settings屬性
與 pom 屬性同理,使用者使用以 settings. 開頭的屬性引用 settings.xml 檔案中的 XML 元素的值
Java系統屬性
所有 java 系統屬性都可以用 maven 屬性引用,如 ${user.home} 指向了使用者目錄
環境變量屬性
所有環境變量屬性都可以使用以 env. 開頭的 maven 屬性引用,如 ${env.JAVA_HOME} 指代了 JAVA_HOME 環境變量的的值
聚合與繼承的關系
1、聚合主要是為了友善快速建構項目,繼承主要是為了消除重複配置
2、對于聚合子產品而言,它知道有哪些被聚合的子產品,但那些被聚合的子產品不知道這個聚合子產品的存在;對于繼承的父pom 而言,它不知道有哪些子子產品繼承它,但那些子子產品都必須知道自己的父pom 是什麼
3、聚合pom 與繼承中的父pom 的 packaging 都必須是 pom;同時,聚合子產品與繼承中的父子產品除了 pom 外,都沒有實際的内容
結束語
maven越來越流行,這方面的資料也是越來越多,《Maven實戰》給我的感覺就相當不錯,本部落格的内容大多取自其中;網上資料也越來越多,就部落格園中就有不少;
最後強調一點:看了是好,實踐更好,寫部落格記錄下來那是最好!