一、概念:
Maven是一個項目管理工具,它包含了一個項目對象模型(Project Object Model),一組標准集合,一個項目生命周期(Project Lifecycle),一個依賴管理系統(Dependency Management System),和用來運行定義在生命周期階段(phase)中插件(plugin)目標(goal)的邏輯。
1、項目構建流程:
2、Maven項目目錄:
二、倉庫:
Maven的倉庫三種:本地倉庫、中央倉庫、遠程倉庫;
(一) 本地倉庫:
本地倉庫是指 maven 下載了插件或者 jar 文件后存放在本地機器上的拷貝。在 Linux 上,它的位置在 ~/.m2/repository,在 Windows XP 上,在 C:\Documents and Settings\username\.m2\repository ,在 Windows 7 上,在 C:\Users\username\.m2\repository。當 maven 查找需要的 jar 文件時,它會先在本地倉庫中尋找,只有在找不到的情況下,才會去遠程庫中找。
可以在%MAVEN_HOME%/conf/settings.xml中設置localRepository的值來修改本地倉庫路徑
運行 mvn install 可以把我們的項目安裝到本地庫;
(二) 中央倉庫:
Maven的中央倉庫由Maven社區提供,默認地址是http://repo1.maven.org/maven2,所有不在本地倉庫中的依賴都會去這個中央倉庫查找。然后Maven會將這些依賴下載到你的本地倉庫。訪問中央倉庫不需要做額外的配置。
(三) 遠程倉庫:
遠程倉庫一般用於放置組織內部的項目,該項目由多個項目共享;
遠程倉庫是位於web服務器上的一個倉庫,Maven可以從該倉庫下載依賴,就像從中央倉庫下載依賴一樣。遠程倉庫可以位於Internet上的任何地方,也可以是位於本地網絡中。
遠程倉庫不能被外部訪問,因此不能放在公開的中央倉庫下,而應該放到內部的遠程倉庫中。
遠程倉庫中的依賴也會被Maven下載到本地倉庫中。
可以在pom文件里配置遠程倉庫。將以下的xml片段放到屬性之后:
1 <repositories> 2 <repository> 3 <id>jenkov.code</id> 4 <url>http://maven.jenkov.com/maven2/lib</url> 5 </repository> 6 </repositories> |
三、安裝:
1、JDK的安裝;
2、在Apache的官網上http://maven.apache.org/download.cgi下載最新版本的Binary zip archive包並解壓到硬盤上的某個路徑下;
3、配置環境變量:
a) 添加環境變量M2_HOME,值為maven包的路徑;
b) 在環境變量PATH里面添加maven的bin的路徑;
4、測試安裝是否成功:
在cmd命令行窗口下輸入:mvn –version,如果顯示出maven的版本號,則說明安裝成功;
5、Eclipse配置:
a) 配置maven的安裝路徑:
在上圖中點擊“Add”按鈕,然后Maven的路徑,確定后就會在列表中顯示;
b) 配置maven 本地庫的路徑:
在上圖中點擊“Browser”按鈕,選擇maven路徑下的settings.xml文件,settings.xml中配置的localRepository項的值就會顯示在下面;
c) 運行參數配置:
選擇jdk項,點擊“編輯”按鈕,在下面的缺省VM參數里面輸入:
-Dmaven.multiModuleProjectDirectory=$M2_HOME
四、常用命令:
五、生命周期:
1、 Maven有三個內嵌的生命周期:clean是刪除target目錄中之前生成的.class和.jar等文件;default是默認生命周期,負責項目的編譯和打包; site關注的是為項目生成文檔,實際上site可以為項目生成一個網頁式的文檔。
2、 每一個生命周期被分為一系列的構建階段,構建階段又被分為一系列的構建目標。因此,整個構建過程由一系列的生命周期、構建階段和構建目標組成。
3、 你可以執行一個生命周期,如clean或site,一個構建階段,如default生命期的install,或者一個構建目標,如dependency:copy-dependencies。注意:你不能直接執行default生命期,你需要指定default生命期中的一個構建階段或者構建目標。
4、 將構建階段的名稱作為參數傳給mvn命令,就是執行該構建階段,如:mvn package。
(一) Clean清理項目:
a) pre-clean 執行清理前的工作
b) clean 清理上一次構建生成的所有文件
c) post-clean 執行清理后的文件
(二) Default構建項目:
d) compile 編譯項目中的源代碼;
e) test 使用合適的單元測試框架進行測試,這些測試代碼不會被打包或部署;
f) test-compile 將需要測試的源代碼編譯到路徑,一般是編譯src/test/java目錄下的java文件至目標輸出的測試classpath目錄中;
g) package 接受編譯好的代碼,打包成可發布的格式,如JAR;
h) install 將包安裝到本地倉庫,給其他本地引用提供依賴;
(三) Site生成項目站點:
i) pre-site 在生成項目站點前要完成的工作;
j) site 生成項目的站點文檔;
k) post-site 在生成項目站點后要完成的工作;
l) site-deploy 發布生成的站點到服務器上;
六、新建maven項目:
1、新建maven工程:
2、選擇工程類型 (Version -RELEASE):
3、輸入工程信息:
4、運行項目:
單擊右鍵項目"run as"--->maven build,在Navigator視圖下可以看到target目錄下有文件了。
注意:如果運行時提示“No goals have been specified for this build…………”,則需要打開運行配置窗口,然后在Goals中輸入“compile”就行:
七、POM文件:
1、dependencyManagement與dependencies的區別:
dependencies:所有聲明在父項目中 dependencies 里的依賴都會被子項目自動引入,並默認被所有的子項目繼承。即使在子項目中不寫該依賴項,那么子項目仍然會從父項目中繼承該依賴項(全部繼承)
dependencyManagement :只是聲明依賴,並不實現引入,因此子項目需要顯示的聲明需要用的依賴。如果不在子項目中聲明依賴,是不會從父項目中繼承下來的;只有在子項目中寫了該依賴項,並且沒有指定具體版本,才會從父項目中繼承該項,並且 version 和 scope 都讀取自父 pom; 另外如果子項目中指定了版本號,那么會使用子項目中指定的jar版本。
比如如下配置:
首先在父POM中定義:
1 <properties> 2 <javaee-api.version>1.0-SNAPSHOT</javaee-api.version> 3 </properties> 4 <dependencyManagement> 5 <dependencies> 6 <dependency> 7 <groupId>javax</groupId> 8 <artifactId>javaee-api</artifactId> 9 <version>${javaee-api.version}</version> 10 </dependency> 11 </dependencies> 12 </dependencyManagement> |
接着在子POM中定義如下:
1 <parent> 2 <artifactId>parent</artifactId> 3 <groupId>com.zhisheng</groupId> 4 <version>0.0.1-SNAPSHOT</version> 5 </parent> 6 <dependencies> 7 <dependency> 8 <groupId>javax</groupId> 9 <artifactId>javaee-api</artifactId> 10 </dependency> 11 </dependencies> |
2、plugins與dependencyManagement的區別:
pluginManagement是表示插件聲明,即你在項目中的pluginManagement下聲明了插件,Maven不會加載該插件,pluginManagement聲明可以被繼承。pluginManagement一般是用來在父POM中定義,提供給子POM使用,子POM也可以覆蓋這個定義,而且你在父POM中定義了版本之后,子模塊中直接應用groupId和artifactId,而不用指定版本,同時也方便統一管理;而在父POM中的pluginManagement並不會介入到Maven的生命周期。pluginManagement主要是為了統一管理插件,確保所有子POM使用的插件版本保持一致,類似dependencies和dependencyManagement。
Plugins:就是直接引入一個plugin,而且可以綁定到Maven相關的生命周期上。
八、依賴管理:
1、假設你的項目依賴於一個庫,而這個庫又依賴於其他庫。你不必自己去找出所有這些依賴,你只需要加上你直接依賴的庫,Maven會隱式的把這些庫間接依賴的庫也加入到你的項目中。
2、傳遞性依賴的嵌套深度沒有任何限制,只是在出現循環依賴時會報錯。
3、“短路徑優先”意味着項目依賴關系樹中路徑最短的版本會被使用。例如,假設A、B、C之間的依賴關系是A->B->C->D(2.0)和A->E->(D1.0),那么D(1.0)會被使用,因為A通過E到D的路徑更短。但如果你想要強制使用D(2.0),那你也可以在A中顯式聲明對D(2.0)的依賴。
4、依賴范圍 – 你可以指定只在當前編譯范圍內包含合適的依賴。
a) Compile:這是默認范圍。如果沒有指定,就會使用該依賴范圍。編譯依賴對項目所有的classpath都可用。此外,編譯依賴會傳遞到依賴的項目。
b) Provided:和compile范圍很類似,但provided范圍表明你希望由JDK或者某個容器提供運行時依賴。例如,當使用Java EE構建一個web應用時,你會設置對Servlet API和相關的Java EE APIs的依賴范圍為provided,因為web容器提供了運行時的依賴。provided依賴只對編譯和測試classpath有效,並且不能傳遞。
c) runtime:runtime范圍表明編譯時不需要依賴,而只在運行時依賴。此依賴范圍對運行和測試classpath有效,對編譯classpath無效。
d) test:test范圍表明使用此依賴范圍的依賴,只在編譯測試代碼和運行測試的時候需要,應用的正常運行不需要此類依賴。
e) system:系統范圍與provided類似,不過你必須顯式指定一個本地系統路徑的JAR,此類依賴應該一直有效,Maven也不會去倉庫中尋找它。
f) import(Maven2.0.9及以上):import范圍只適用於pom文件中的部分。表明指定的POM必須使用部分的依賴。因為依賴已經被替換,所以使用import范圍的依賴並不影響依賴傳遞。
5、排除依賴 – 如果項目X依賴於項目Y,項目Y又依賴項目Z,項目X的所有者可以使用”exclusion”元素來顯式排除項目Z。
6、可選依賴 – 如果項目Y依賴項目Z,項目Y的所有者可以使用”optional”元素來指定項目Z作為X的可選依賴。那么當項目X依賴項目Y時,X只依賴Y並不依賴Y的可選依賴Z。項目X的所有者也可以根據自己的意願顯式指定X對Z的依賴。(你可以把可選依賴理解為默認排除)。
(一) 項目依賴:
項目A依賴項目B,項目B依賴項目C.眾多的項目形成一個有向無環圖(DAG),使用maven,就可以自動推導出項目所依賴的全部jar包。
在pom.xml中進行如下配置:
1 <dependencies> 2 <dependency> 3 <groupId>org.jsoup</groupId> 4 <artifactId>jsoup</artifactId> 5 <version>1.7.1</version> 6 </dependency> 7 <dependency> 8 <groupId>junit</groupId> 9 <artifactId>junit</artifactId> 10 <version>4.8.1</version> 11 <scope>test</scope> 12 </dependency> 13 </dependencies> |
(二) 外部依賴:
有時只有一個jar包而沒有它的groupId和artifactId,並且三種maven倉庫中都沒有這個jar包項目,但當前項目依賴這個jar包,這種依賴叫做外部依賴。
有兩個方法解決:
1、在每個maven項目的pom.xml文件中如下配置:
1 <dependency> 2 <groupId>mydependency</groupId> 3 <artifactId>mydependency</artifactId> 4 <scope>system</scope> 5 <version>1.0</version> 6 <systemPath>${basedir}\mydependency.jar</systemPath> 7 </dependency> |
2、方法一太過麻煩,可以將第三方jar包安裝到本地maven倉庫中去:
mvn install:install-file -Dfile=xxx -DgroupId=xxx -DartifactId=xxx -Dversion=xxx -Dpackaging=xxx
其中packaging是打包類型,可以取值war,jar等。
如果第三方jar包有相應的pom.xml,則不必提供groupId,artifactId等信息,因為它們都在pom.xml里面寫着呢.可以使用如下命令:
mvn install:install-file -Dfile=xxx -DpomFile=xxx
(三) 快照依賴:
快照依賴指的是那些還在開發中的依賴(jar包)。與其經常地更新版本號來獲取最新版本,不如你直接依賴項目的快照版本。快照版本的每一個build版本都會被下載到本地倉庫,即使該快照版本已經在本地倉庫了。總是下載快照依賴可以確保本地倉庫中的每一個build版本都是最新的。
在pom文件的最開頭的版本號后追加-SNAPSHOT,則告訴Maven你的項目是一個快照版本。如:
<version>1.0-SNAPSHOT</version>
在配置依賴時,在版本號后追加-SNAPSHOT表明依賴的是一個快照版本。
九、Maven工程類型:
Maven工程類型有三種:
1、WAR包工程;
2、JAR包工程;
3、POM工程;
工程之間的關系:
1、依賴:通過在 dependencies 元素下添加 dependency 子元素,可以聲明一個或多個依賴。
依賴是具有傳遞性的。
2、聚合:一個項目往往是由多個 project 構成的,在進行構建時,我們當然不想針對多個 project 分別執行多次構建命令,這樣極容易產生遺漏也會大大降低效率。Maven的聚合功能可以通過一個父模塊將所有的要構建模塊整合起來,將父模塊的打包類型聲明為 POM,通過 <modules> 將各模塊集中到父 POM 中。配置如下:
1 <modules> 2 <module>../com.dugeng.project1</module> 3 <module>../com.dugeng.project2</module> 4 </modules> |
父類型的模塊,不需要有源代碼和資源文件,也就是說,沒有 src/main/java 和 src/test/java 目錄。Maven 會首先解析聚合模塊的 POM 文件,分析要構建的模塊,並通過各模塊的依賴關系計算出模塊的執行順序,根據這個潛在的關系依次構建模塊。將各子模塊聚合到父模塊中后,我們就可以對父模塊進行一次構建命令來完成全部模塊的構建。
3、繼承:通過構建父模塊將子模塊共用的依賴,插件等進行統一聲明。
例如將 com.dugeng.parent 這個模塊聲明為 project1 和 project2 的父模塊,那么我們在 project1 和 2 中用如下代碼聲明父子關系:
1 <parent> 2 <groupId>com.dugeng.mavenproject</groupId> 3 <artifactId>com.dugeng.parent</artifactId> 4 <version>0.0.1-SNAPSHOT</version> 5 <relativePath>../com.dugeng.parent/pom.xml</relativePath> 6 </parent> |
由於父模塊只是用來聲明一些可共用的配置和插件信息,所以它也像聚合模塊一樣只需要包括一個 POM 文件,其它的項目文件如 src/main/java 是不需要的。
父工程應該是一個POM工程;