Maven入門指南(二)
轉載自並發編程網 – ifeve.com本文鏈接地址: Maven入門指南(二)
Maven目錄結構
Maven有一個標準的目錄結構。如果你在項目中遵循Maven的目錄結構,就無需在pom文件中指定源代碼、測試代碼等目錄。
Maven的目錄結構布局,參考Maven標準目錄結構介紹
以下為最重要的目錄:
- src - main - java - resources - webapp - test - java - resources - target
src目錄是源代碼和測試代碼的根目錄。main目錄是應用的源代碼目錄。test目錄是測試代碼的目錄。main和test下的java目錄,分別表示應用的java源代碼和測試代碼。
resources目錄包含項目的資源文件,比如應用的國際化配置的屬性文件等。
如果是一個web項目,則webapp目錄為web項目的根目錄,其中包含如WEB-INF等子目錄。
target目錄是由Maven創建的,其中包含編譯後的類文件、jar文件等。當執行maven的clean
目標後,target目錄會被清空。
項目依賴
除非你的項目很小,否則會需要外部的Java API或者框架以jar包形式提供的依賴。當你編譯項目代碼的時候,需要classpath上的這些jar包。
使項目依賴的外部jar包以正確的版本保持最新狀態,是一項艱巨的任務。而且,這些外部的jar包還會依賴其它的外部jar包。遞歸地下載所有這些外部依賴(jar包),並且要確保下載的版本都是正確的,是非常麻煩的。尤其是當項目變得越來越大,外部依賴越來越多的時候。
幸運的是,Maven內嵌有依賴管理的功能。你只需要在pom文件裏指定依賴jar包的名稱、版本號,Maven會自動下載並放到你的Maven本地倉庫中。如果這些外部jar包依賴了其它的庫,它們也會被下載到你的Maven本地倉庫。
在pom文件的dependencies
屬性中指定項目依賴,如:
<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.jenkov.crawler</groupId> <artifactId>java-web-crawler</artifactId> <version>1.0.0</version> <dependencies> <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artifactId> <version>1.7.1</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> </dependencies> <build> </build> </project>
在dependencies
屬性下有兩個dependency
子屬性,每一個dependency
屬性描述了一個外部依賴。
每一個依賴由groupId, artifactId和version來描述。如果你有印象,這和我們在pom文件的開頭用來標識項目的方式是一樣的。上面的示例表明,項目的依賴為 org.jsoup組織下的1.7.1版本的jsoup,以及junit組織下的4.8.1版本的junit。
當Maven執行該pom文件時,將從Maven的中央倉庫裏下載這兩個jar包並放到Maven的本地倉庫。如果本地倉庫中已經有了這兩個依賴,Maven就不會去下載了。只有本地倉庫中沒有的依賴才會被下載。
有的時候,指定的依賴在Maven的中央倉庫裏沒有。你可以直接下載這些依賴,然後放到Maven的本地倉庫。這些依賴必須放到與groupId、 artifactId和version匹配的子目錄中。用/替換所有的點(.)並且使用/分隔groupId、artifactId和version,這 就是與該依賴匹配的子目錄。
上面示例中的兩個依賴將會被放到以下子目錄中:
MAVEN_REPOSITORY_ROOT/junit/junit/4.8.1 MAVEN_REPOSITORY_ROOT/org/jsoup/jsoup/1.7.1
外部依賴
Maven的外部依賴指的是不在Maven的倉庫(包括本地倉庫、中央倉庫和遠程倉庫)中的依賴(jar包)。它可能位於你本地硬盤的某個地方,比如web應用的lib目錄下。這裏的“外部”是對Maven倉庫系統而言的,不僅僅是對項目而言的。大部分的外部依賴都是針對項目的,很少的外部依賴是針對倉庫系統的(即不在倉庫中)。
配置外部依賴的示例如下:
<dependency> <groupId>mydependency</groupId> <artifactId>mydependency</artifactId> <scope>system</scope> <version>1.0</version> <systemPath>${basedir}\war\WEB-INF\lib\mydependency.jar</systemPath> </dependency>
groupId和artifactId為依賴的名稱,即API的名稱。scope屬性為system。systemPath屬性為jar文件的路徑。${basedir}為pom文件所在的目錄,路徑中的其它部分是相對於該目錄而言的。
快照依賴
快照依賴指的是那些還在開發中的依賴(jar包)。與其經常地更新版本號來獲取最新版本,不如你直接依賴項目的快照版本。快照版本的每一個build版本都會被下載到本地倉庫,即使該快照版本已經在本地倉庫了。總是下載快照依賴可以確保本地倉庫中的每一個build版本都是最新的。
在pom文件的最開頭(設置groupId和artifactId的地方),在版本號後追加-SNAPSHOT,則告訴Maven你的項目是一個快照版本。如:
<version>1.0-SNAPSHOT</version>
可以看到加到版本號後的-SNAPSHOT。
在配置依賴時,在版本號後追加-SNAPSHOT表明依賴的是一個快照版本。如:
<dependency> <groupId>com.jenkov</groupId> <artifactId>java-web-crawler</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
追加在version後的-SNAPSHOT告訴Maven這是一個快照版本。
可以在Maven配置文件中設置快照版本下載的頻率。
Maven倉庫
Maven倉庫就是存儲jar包和一些元數據信息的目錄。其中的元數據即pom文件,描述了該jar包屬於哪個項目,以及jar包所需的外部依賴。該元數據信息使得Maven可以遞歸地下載所有的依賴,直到整個依賴樹都下載完畢並放到你的本地倉庫中。
Maven倉庫的詳細介紹參考Maven 倉庫介紹,快速介紹如下:
Maven有三種類型的倉庫:
- 本地倉庫
- 中央倉庫
- 遠程倉庫
Maven根據以上的順序去倉庫中搜索依賴。首先是本地倉庫,然後是中央倉庫,最後,如果pom文件中配置了遠程倉庫,則會去遠程倉庫中查找。
下圖說明了三種倉庫的類型以及位置:
本地倉庫
本地倉庫就是開發者電腦上的一個目錄。該倉庫包含了Maven下載的所有依賴。一般來講,一個本地倉庫為多個不同的項目服務。因此,Maven只需下載一次,即使有多個項目都依賴它(如junit)。
通過mvn install
命令可以將你自己的項目構建並安裝到本地倉庫中。這樣,你的其它項目就可以通過在pom文件將該jar包作為外部依賴來使用。
Maven的本地倉庫默認在你本機的用戶目錄下。不過,你可以在Maven的配置文件中修改本地倉庫的路徑。Maven的配置文件也在用戶目錄下(user-home/.m2),文件名為settings.xml。以下示例為本地倉庫指定其它的路徑:
<settings> <localRepository> d:\data\java\products\maven\repository </localRepository> </settings>
中央倉庫
Maven的中央倉庫由Maven社區提供。默認情況下,所有不在本地倉庫中的依賴都會去這個中央倉庫查找。然後Maven會將這些依賴下載到你的本地倉庫。訪問中央倉庫不需要做額外的配置。
遠程倉庫
遠程倉庫是位於web服務器上的一個倉庫,Maven可以從該倉庫下載依賴,就像從中央倉庫下載依賴一樣。遠程倉庫可以位於Internet上的任何地方,也可以是位於本地網絡中。
遠程倉庫一般用於放置組織內部的項目,該項目由多個項目共享。比如,由多個內部項目共用的安全項目。該安全項目不能被外部訪問,因此不能放在公開的中央倉庫下,而應該放到內部的遠程倉庫中。
遠程倉庫中的依賴也會被Maven下載到本地倉庫中。
可以在pom文件裏配置遠程倉庫。將以下的xml片段放到屬性之後:
<repositories> <repository> <id>jenkov.code</id> <url>http://maven.jenkov.com/maven2/lib</url> </repository> </repositories>
Maven的構建生命周期、階段和目標
當使用Maven構建項目時,會遵循一個構建生命周期。該生命周期分為多個構建階段,而構建階段又分為多個構建目標。Maven的構建周期、構建階段和目標的更多細節請參考Maven構建周期介紹,這裏是一個快速介紹。
構建生命周期
Maven有三個內嵌的構建生命周期:
- default
- clean
- site
每一個構建生命期關註項目構建的不同方面。因此,它們是獨立地執行的。Maven可以執行多個生命期,但是它們是串行執行的,相互獨立,就像你執行了多條獨立的Maven命令。
default
生命期關註的是項目的編譯和打包。clean
生命期關註的是從輸出目錄中刪掉臨時文件,包括自動生成的源文件、編譯後的類文件,之前版本的jar文件等。site
生命期關註的是為項目生成文檔。實際上,site
可以使用文檔為項目生成一個完整的網站。
構建階段
每一個構建生命期被分為一系列的構建階段,構建階段又被分為構建目標。因此,整個構建過程由一系列的構建生命期、構建階段和構建目標組成。
你可以執行一個構建生命期,如clean
或site
,一個構建階段,如default
生命期的install
,或者一個構建目標,如dependency:copy-dependencies
。註意:你不能直接執行default
生命期,你需要指定default
生命期中的一個構建階段或者構建目標。
當你執行一個構建階段時,所有在該構建階段之前的構建階段(根據標準構建順序)都會被執行。因此,執行install
階段,意味著所有位於install
階段前的構建階段都會被執行,然後才執行install
階段。
default
生命期更多的關註於構建代碼。由於你不能直接執行default
生命期,你需要執行其中一個構建階段或者構建目標。default
生命期包含了相當多的構建階段和目標,這裏不會所有都介紹。最常用的構建階段有:
構建階段 描述 validate 驗證項目的正確性,以及所有必需的信息都是否都存在。同時也會確認項目的依賴是否都下載完畢。 compile 編譯項目的源代碼 test 選擇合適的單元測試框架,對編譯後的源碼執行測試;這些測試不需要代碼被打包或者部署。 package 將編譯後的代碼以可分配的形式打包,如Jar包。 install 將項目打包後安裝到本地倉庫,可以作為其它項目的本地依賴。 deploy 將最終的包復制到遠程倉庫,與其它開發者和項目共享。
將構建階段的名稱作為參數傳給mvn
命令,就是執行該構建階段,如:
mvn package
該示例執行package
構建階段,因此在Maven的構建階段序列中所有位於該階段之前的階段也都會被執行。
如果標準的Maven構建階段和目標無法滿足項目的需要,可以創建Maven插件增加你需要的構建功能。
構建目標
構建目標是Maven構建過程中最細化的步驟。一個目標可以與一個或多個構建階段綁定,也可以不綁定。如果一個目標沒有與任何構建階段綁定,你只能將該目標的名稱作為參數傳遞給mvn
命令來執行它。如果一個目標綁定到多個構建階段,該目標在綁定的構建階段執行的同時被執行。
Maven構建配置
Maven構建配置使你能使用不同的配置來構建項目。不用創建兩個獨立的pom文件。你只需使用不同的構建配置指定不同的配置文件,然後使用該配置文件構建項目即可。
關於構建配置的詳細信息可以參考Maven POM參考的Profile部分。這裏是一個快速的介紹。
Maven的構建配置在pom文件的profiles
屬性中指定,例如:
<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.jenkov.crawler</groupId> <artifactId>java-web-crawler</artifactId> <version>1.0.0</version> <profiles> <profile> <id>test</id> <activation>...</activation> <build>...</build> <modules>...</modules> <repositories>...</repositories> <pluginRepositories>...</pluginRepositories> <dependencies>...</dependencies> <reporting>...</reporting> <dependencyManagement>...</dependencyManagement> <distributionManagement>...</distributionManagement> </profile> </profiles> </project>
構建配置描述的是當使用該配置構建項目時,對pom文件所做的修改,比如修改應用使用的配置文件等。profile
屬性中的值將會覆蓋其上層的、位於pom文件中的配置。
在profile
屬性中,有一個activation
子屬性。該屬性指定了啟用該構建配置的條件。選擇構建配置的一種方式是在settings.xml
文件中指定;另一種方式是在Maven命令行使用-P profile-name
指定。更多細節參考構建配置的文檔。
Maven插件
使用Maven插件,可以向構建過程添加自定義的動作。創建一個簡單的Java類,該類繼承一個特殊的Maven類,然後為項目創建一個pom文件。該插件應該位於其項目下。
為了使本教程簡短,關於開發插件的更多細節請參考Maven插件開發中心
Maven入門指南(二)