Maven學習(一) - Maven基礎

Maven做爲Java語言的構建和依賴管理工具,已經被普遍使用。但對於maven的pom.xml的配置以及插件的使用,大部分人也僅僅限於瞭解的程度。工欲善其事,必先利其器。在拖延了好久後,決定仍是花時間根據《maven實戰》這個書來進一步深刻了解maven的使用。這個系列是在學習maven過程當中的筆記和總結,聊以記錄,利人利己。html

maven座標定義

  • groupId:當前maven項目隸屬的實際項目,不止要到公司或組織,而應該到實際項目,應爲項目每每會劃分紅多個模塊,如org.sonatype.nexus,org.sonatype是一個組織,nexus是一個實際項目
  • artifactId:實際項目中的一個maven項目(模塊),推薦使用實際項目名做爲artifactId的前綴,好比上面的nexus的索引模塊可爲nexus-indexer,這樣可區分不一樣實際項目的一些基礎模塊,好比base或core等模塊
  • version:版本
  • packaging:maven項目的打包方式,jar打包和war打包構建的生命週期會有不一樣的命令,默認爲jar
  • classifier:用來幫助定義構建輸出的一些附屬構件,如javadoc或sources。注意,不能直接定義項目的classifier,由於附屬構件不是項目直接默認生成的,而是由附加的插件幫助生成的。

項目構建的文件名是與座標相對應的,通常的規則是artifactId-version[-classifier].packaging,[-classifier]爲可選java

maven依賴配置

pom.xml中<dependencies>標籤下包含一個或多個<dependence>元素,來聲明一個或多個項目依賴。每一個依賴能夠包含的元素有spring

  • groupId、artifactId和version:依賴的基本座標
  • type:依賴的類型,對應項目座標的packaging
  • scope:依賴範圍
  • optional:標記依賴是否可選
  • exclusions:用來排除傳遞性依賴

依賴範圍

  • compile:scope默認依賴範圍,對於編譯,測試,運行三種classpath都有效,如spring-core
  • test:只對於測試classpath有效,如JUnit
  • provided:對編譯和測試classpath有效,運行時無效。如servlet-api,由於運行時容器已經提供,不須要maven重複引入
  • runtime:測試和運行時classpath有效如JDBC驅動實現,編譯時只須要JDK提供的JDBC接口
  • system:同provided範圍一致,使用system範圍的依賴不是經過maven倉庫解析,而是經過systemPath元素顯示指定依賴文件。由於可能形成構建的不可移植,應謹慎使用。

依賴傳遞

若是項目的依賴有本身的依賴,則項目也會加載依賴的依賴。好比spring-core依賴commons-logging,若是項目依賴了spring-core,那麼它也會依賴commons-logging。當依賴的聲明爲可選時(<optional>true</optional>),依賴不會傳遞。apache

依賴調解

由於存在依賴傳遞,就會有不一樣的依賴中有不一樣版本的基礎依賴,如A -> X(1.0),B -> C -> X(2.0),這樣X就有不一樣的版本,哪一個會被maven解析呢?因而就有了依賴調解的兩個原則:api

  1. 路徑最近者優。,如上X(1.0)的路徑爲1,而X(2.0)的路徑爲2,所以X(1.0)會被使用
  2. 同等路徑下,第一聲明者優先。在路徑長度都一致時,pom.xml中順序靠前的被使用。

依賴排除

項目中可能存在,由於一些緣由,不想引入某依賴的傳遞性依賴,則可使用exclusions。好比在使用spring時不想用commons-logging,則能夠在spring-core中排除。maven

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>5.0.0.M5</version>
	<exclusions>
		<exclusion>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
		</exclusion>
	</exclusions>
</dependency>

依賴版本歸類

好比在使用spring時,可能會用到spring-context,spring-jdbc,spring-tx等,但他們的版本是一致的,考慮到之後版本的升級,能夠定義一個spring.version的properties來統一設置版本。ide

<properties>
    <spring.version>4.1.6.RELEASE</spring.version>
</properties>

而在依賴的<version>中用${spring.version}代替工具

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>${spring.version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jdbc</artifactId>
	<version>${spring.version}</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-tx</artifactId>
	<version>${spring.version}</version>
</dependency>

依賴查看與分析

// 查看項目依賴列表
mvn dependency:list
// 以樹狀顯示依賴列表
mvn dependency:tree
// 依賴分析
mvn dependency:analyze

maven生命週期

maven有三套相互獨立的生命週期,分別是clean,default,site。學習

  • clean的目的是清理項目
  • default的目的是構建項目
  • site的目的是創建項目站點

每一個生命週期包含一些階段(phase),這些階段是有順序的,而且後面的階段依賴於前面的階段。default是生命週期中最核心的部分,它包含不少階段,如下是常見的幾種階段,全量的階段可見http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference。測試

  • validate:驗證項目是否正確
  • compile:編譯項目源代碼
  • test:使用一個測試套件測試編譯後的代碼
  • package:打包項目代碼
  • verify:檢查集成測試結果
  • install:將打包好的項目代碼安裝到本地倉庫
  • deploy:複製最後的打包結果到遠程倉庫

咱們能夠用命令行來執行生命週期階段

  • mvn clean:調用clean生命週期的clean階段,包含pre-clean和clean階段
  • mvn test:調用default生命週期的test階段,包含validate到test的全部階段
  • mvn clean install:調用clean生命週期的clean階段和default生命週期的install階段,實際執行的是clean生命週期的pre-clean,clean階段和default生命週期從validate至install的全部階段

maven插件

插件目標

咱們知道maven的核心只定義了抽象的生命週期,具體的任務是交由插件完成的,插件以獨立的構件存在,maven會在須要時下載並使用插件。對於一個插件,可能會有多個功能,每一個功能就對應一個插件目標(Plugin Goal)。

好比maven-dependency-plugin有多個目標,如dependency:list,dependency:tree,dependency:analyze等,冒號前是插件前綴,冒號後是插件目標。相似的,compiler:compile(maven-compiler-plugin的compile目標)和surefire:test(maven-surefire-plugin的test目標)。

在使用時,須要將生命週期的階段和插件目標相互綁定,以完成某個具體的構建任務。如maven-compiler-plugin的compile目標綁定的就是default生命週期的compile階段。

maven內置了不少生命週期階段同插件目標的綁定,好比打包類型爲jar的default生命週期的內置插件綁定關係以下:

生命週期階段 插件目標 執行任務
process-resources maven-resources-plugin:resources 複製主資源文件至主輸出目錄
compile maven-compiler-plugin:compile 編譯主代碼至主輸出目錄
process-test-resources maven-resources-plugin:testResources 複製測試資源文件至測試輸出目錄
test-compile maven-compiler-plugin:testCompile 編譯測試代碼至測試輸出目錄
test maven-surefire-plugin:test 執行測試用例
package maven-jar-plugin:jar 建立項目jar包
install maven-install-plugin:install 將項目輸出構件安裝到本地倉庫
deploy maven-deploy-plugin:deploy 將項目輸出構件部署到遠程倉庫

出了內置的綁定關係外,用戶能夠選擇將某個插件目標綁定到生命週期的某個階段。一個例子是建立項目的源碼jar包,可使用maven-source-plugin的jar-no-fork目標獎項目主代碼打成jar文件,咱們將其綁定到verify階段。

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-source-plugin</artifactId>
	<version>3.0.1</version>
	<executions>
		<execution>
			<id>attach-sources</id>
			<phase>verify</phase>
			<goals>
				<goal>jar-no-fork</goal>
			</goals>
		</execution>
	</executions>
</plugin>

有不少插件的目標在編寫時已經定義了默認綁定階段,可使用命令查看

mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:3.0.1
Ddetail

能夠看到輸出的信息中有

source:jar-no-fork
...
Bound to phase: package

即jar-no-for默認綁定的生命週期階段爲package

插件配置

用戶能夠經過命令行和pom配置來配置插件的參數

1.命令行配置,用戶能夠在maven命令中使用-D參數,指定一個key-value的形式,來配置插件目標的參數。例如maven-surefire-plugin提供了一個maven.test.skip參數,當爲true時,就跳過執行測試。

mvn install -Dmaven.test.skip=true

2.pom中插件全局配置,全部基於該插件目標的任務都會使用此配置,常見的youmaven-compiler-plugin編譯java的版本。

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-compiler-plugin</artifactId>
	<version>2.3.2</version>
	<configuration>
		<source>1.8</source>
		<target>1.8</target>
		<encoding>utf-8</encoding>
	</configuration>
</plugin>

3.用戶能夠爲某個插件任務配置特定的參數,將maven-antrun-plugin:run綁定到多個生命週期階段上,加以不一樣的配置

<plugin>
	<artifactId>maven-antrun-plugin</artifactId>
	<version>1.8</version>
	<executions>
		<execution>
			<id>ant-validate</id>
			<phase>validate</phase>
			<goals>
				<goal>run</goal>
			</goals>
			<configuration>
				<tasks>
					<echo>validate phase</echo>
				</tasks>
			</configuration>
		</execution>
		<execution>
			<id>ant-verify</id>
			<phase>verify</phase>
			<goals>
				<goal>run</goal>
			</goals>
			<configuration>
				<tasks>
					<echo>verify phase</echo>
				</tasks>
			</configuration>
		</execution>
	</executions>
</plugin>

插件查找

能夠從http://maven.apache.org/plugins/index.html中查詢插件的詳細信息,也可使用maven-help-plugin描述插件。

//查詢插件信息
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:3.0.1
//查詢插件目標信息
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:3.0.1 -Dgoal=jar-no-fork
//查詢詳細信息
mvn help:describe -Dplugin=org.apache.maven.plugins:maven-source-plugin:3.0.1 -Ddetail

Maven內置變量

Maven內置了一些目錄變量,對涉及文件路徑的配置會有幫助

  • ${basedir} 項目根目錄
  • ${project.build.directory} 構建目錄,缺省爲target
  • ${project.build.outputDirectory} 構建過程輸出目錄,缺省爲target/classes
  • ${project.build.finalName} 產出物名稱,缺省爲${project.artifactId}-${project.version}
  • ${project.packaging} 打包類型,缺省爲jar
  • ${project.xxx} 當前pom文件的任意節點的內容
相關文章
相關標籤/搜索