Maven是一個專案管理工具,它包含了一個專案物件模型 (Project Object Model),一組標準集合,一個專案生命週期(Project Lifecycle),一個依賴管理系統(Dependency Management System),和用來執行定義在生命週期階段(phase)中外掛(plugin)目標(goal)的邏輯。
核心功能
- 依賴管理:Maven工程對jar包的管理過程。
一個複雜的專案將會包含很多依賴,也有可能包含依賴於其它構件的依賴。這是Maven最強大的特徵之一,它支援了傳遞性依賴(transitive dependencies)。假如你的專案依賴於一個庫,而這個庫又依賴於五個或者十個其它的庫(就像Spring或者Hibernate那樣)。你不必找出所有這些依賴然後把它們寫在你的pom.xml裡,你只需要加上你直接依賴的那些庫,Maven會隱式的把這些庫間接依賴的庫也加入到你的專案中。Maven也會處理這些依賴中的衝突,同時能讓你自定義預設行為,或者排除一些特定的傳遞性依賴。
- 專案構建:
mvn tomcat:run
倉庫
本地倉庫、遠端倉庫(私服)、中央倉庫
本地倉庫預設為{user.home}.m2.repority,可以在配置檔案中修改
Maven專案標準目錄結構
核心程式碼部分:src/main/java
配置檔案部分:src/main/resources
測試程式碼部分:src/test/java
測試配置檔案:src/test/resources
頁面資源(包含js,css,圖片資源等):src/main/webapp
Maven常用命令
clean:刪除專案中已經編譯好的資訊,刪除target目錄
compile:Maven工程的編譯命令,用於編譯專案的原始碼,將src/main/java
下的檔案編譯成class檔案輸出到target目錄下。
test:使用合適的單元測試框架執行測試。
package:將編譯好的程式碼打包成可分發的格式,如JAR,WAR。
install:安裝包至本地倉庫,以備本地的其它專案作為依賴使用。
deploy:複製最終的包至遠端倉庫,共享給其它開發人員和專案(通常和一次正式的釋出相關)。
每一個構建專案的命令都對應了maven底層一個外掛。
Maven命令package、install、deploy的聯絡與區別
mvn clean package依次執行了clean、resources、compile、testResources、testCompile、test、jar(打包)等7個階段。
mvn clean install依次執行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install等8個階段。
mvn clean deploy依次執行了clean、resources、compile、testResources、testCompile、test、jar(打包)、install、deploy等9個階段。
主要區別:
package命令完成了專案編譯、單元測試、打包功能,但沒有把打好的可執行jar包(war包或其它形式的包)佈署到本地maven倉庫和遠端maven私服倉庫。
install命令完成了專案編譯、單元測試、打包功能,同時把打好的可執行jar包(war包或其它形式的包)佈署到本地maven倉庫,但沒有佈署到遠端maven私服倉庫。
deploy命令完成了專案編譯、單元測試、打包功能,同時把打好的可執行jar包(war包或其它形式的包)佈署到本地maven倉庫和遠端maven私服倉庫。
Maven生命週期
清理生命週期:執行mvn clean將呼叫清理生命週期 。
預設生命週期:是一個軟體應用程式構建過程的總體模型 。
compile,test,package,install,deploy
站點生命週期:為一個或者一組專案生成專案文件和報告,使用較少。
Maven概念模型
專案物件模型(Project Object Model,POM),對應著Maven專案中的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>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.shangguan</groupId>
<artifactId>concurrency</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>concurrency</name>
<description>Demo project for Spring Boot</description>
專案執行所依賴的jar包資訊,如:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<groupId>
:團體,公司,小組,組織,專案,或者其它團體。團體標識的約定是,它以建立這個專案的組織名稱的逆向域名(reverse domain name)開頭。
<artifactId>
:專案的唯一識別符號
version
:專案的版本
package
:專案的型別,預設是jar,描述了專案打包後的輸出 。
專案執行環境資訊,比如:jdk,tomcat資訊
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
依賴範圍
compile:預設的範圍,編譯測試執行都有效。
provided:編譯和執行有效,最後在執行的時候不會加入。官方舉了一個例子。比如在JavaEE web專案中我們需要使用servlet的API,但是Tomcat中已經提供這個jar,我們在編譯和測試的時候需要使用這個api,但是部署到tomcat的時候,如果還加入servlet構建就會產生衝突,這個時候就可以使用provided。
runtime:測試和執行有效。
test:測試有效。
system:與本機系統關聯,編譯和測試時有效。
import:匯入的範圍,它只在使用dependencyManagement中,表示從其他pom中匯入dependecy的配置。
Maven依賴衝突
每個顯式宣告的類包都會依賴於一些其它的隱式類包,這些隱式的類包會被maven間接引入進來,因而可能造成一個我們不想要的類包的載入,嚴重的甚至會引起類包之間的衝突。
要解決這個問題,首先就是要檢視pom.xml顯式和隱式的依賴類包,然後通過這個類包樹找出我們不想要的依賴類包,手工將其排除在外就可以了。 例如:
<exclusions>
<exclusion>
<artifactId>unitils-database</artifactId>
<groupId>org.unitils</groupId>
</exclusion>
</exclusions>