Maven(二)maven核心概念

一、Maven中的幾個概念

1. POM

我們在上篇文章中提到了maven的幾個核心概念,其中一個是POM。
POM就是Project Object Model項目對象模型。
將 Java 工程的相關信息封裝爲對象作爲便於操作和管理的模型
pom.xml就是Maven 工程的核心配置。可以說學習 Maven 就是學習 pom.xml 文件中的配置。

我們會在後面不斷的學習,這裏就先不做展開。

2. 座標

說到座標,我們首先想到的應該是數學中的座標:

  • 在一個平面中使用 x、y 兩個向量可以唯一的確定平面中的一個點。
  • 在空間中使用 x、y、z 三個向量可以唯一的確定空間中的一個點。

而maven中的座標,
使用以下三個向量在Maven倉庫中唯一的確定一個Maven工程。

  1. groupID:公司或組織的域名倒序+當前項目的名稱
  2. artifactID:當前項目的模塊名稱
  3. version:當前模塊的版本

例如:

<groupId>com.atguigu.maven</groupId> 
<artifactId>Hello</artifactId>
<version>0.0.1-SNAPSHOT</version> 

這樣的定位方式我們又簡稱爲GAV,也就是上面三個單詞的首字母縮寫。

Maven工程的座標與倉庫中路徑的對應關係,
例如:
在這裏插入圖片描述

3. 倉庫

分類

倉庫分爲本地倉庫和遠程倉庫。

本地倉庫就是當前電腦上部署的倉庫目錄,爲當前電腦上所有的Maven工程服務。

遠程倉庫又分爲私服、中央倉庫、中央倉庫的鏡像。

  1. 私服:架設在當前局域網環境下,爲當前局域網範圍內的所有 Maven 工程服務。
    在這裏插入圖片描述
  2. 中央倉庫:架設在 Internet 上,爲全世界所有 Maven 工程服務。
  3. 中央倉庫的鏡像:架設在各個大洲,爲中央倉庫分擔流量。減輕中央倉庫的壓力,同時更快的響應用戶請求。

倉庫中的內容

倉庫裏面保存的都是Maven工程。

倉庫中保存着:

  • Maven自身所需要的插件
  • 第三方框架或工具的jar包
  • 我們自己開發的Maven工程

我們爲了介紹Maven的依賴,我們先要建立第二個Maven工程。

二、第2個Maven工程

搭建HelloFriend工程

①工程名:HelloFriend
②目錄結構與第一個Maven工程相同
③POM文件

<?xml version="1.0" ?>
<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.veeja.maven</groupId>
	<artifactId>HelloFriend</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>HelloFriend</name>
	
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.0</version>
			<scope>test</scope>
		</dependency>		
		
		<dependency>
			<groupId>com.veeja.maven</groupId>
			<artifactId>HelloMaven</artifactId>
			<version>0.0.1-SNAPSHOT</version>
			<scope>compile</scope>
		</dependency>
	</dependencies>
</project>

④主程序:
在src/main/java/com/veeja/maven目錄下新建文件HelloFriend.java

package com.veeja.maven;	
import com.veeja.maven.HelloMaven;
public class HelloFriend {
	public String sayHelloToFriend(String name){
		HelloMaven helloMaven = new HelloMaven();
		String str = helloMaven.sayHello(name)+" I am "+this.getMyName();
		System.out.println(str);
		return str;
	}
	public String getMyName(){
		return "John";
	}
}

⑤測試程序:
在/src/test/java/com/atguigu/maven目錄下新建測試文件HelloFriendTest.java

package com.veeja.maven;	
import static junit.framework.Assert.assertEquals;
import org.junit.Test;
import com.veeja.maven.HelloMaven;

public class HelloFriendTest {
	@Test
	public void testHelloFriend(){
		HelloFriend helloFriend = new HelloFriend();
		String results = helloFriend.sayHelloToFriend("veeja");
		assertEquals("Hello veeja! I am John",results);	
	}
}

我們的關注點在於,我們在這個HelloFriend工程裏面,用到了HelloMaven這個工程。這就產生了所謂的“依賴”。而我們爲什麼能使用呢,原因就在於我們在pom.xml中配置了這樣的依賴關係,也就是:

<dependency>
	<groupId>com.veeja.maven</groupId>
	<artifactId>HelloMaven</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<scope>compile</scope>
</dependency>

那麼我們這樣配置到底能不能使用呢?我們接下來要試一試。

執行幾個命令

我們先來執行mvn compile命令,看一下結果:
在這裏插入圖片描述
我們可以看到,構建失敗了,錯誤的信息爲:
[ERROR] Failed to execute goal on project HelloFriend: Could not resolve dependencies for project com.veeja.maven:HelloFriend:jar:0.0.1-SNAPSHOT: Could not find artifact com.veeja.maven:HelloMaven:jar:0.0.1-SNAPSHOT -> [Help 1]
它提示我們,找不到HelloMaven工件。

我們再來思考上面講的座標知識,

<dependency>
	<groupId>com.veeja.maven</groupId>
	<artifactId>HelloMaven</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<scope>compile</scope>
</dependency>

這樣的一段依賴配置,已經確定了對應的目錄。而我們在倉庫中,並沒有找到相應的目錄及文件。
在這裏插入圖片描述

三、依賴

Maven解析依賴信息時會到本地倉庫中查找被依賴的jar包。
對於我們自己開發的Maven工程,使用install命令安裝後就可以進入倉庫。
對於上面的例子中,我們應該先把HelloMaven添加進倉庫中,也就是在HelloMaven工程下執行mvn install
在這裏插入圖片描述
這時呢,我們在進入我們的本地倉庫中,就能找到對應的目錄和文件了。
在這裏插入圖片描述
這時我們再次編譯HelloFriend工程,
在這裏插入圖片描述
我們這次看到,編譯就成功了。

依賴的範圍

我們在配置文件中的<dependency>標籤中,

<dependencies>
	<dependency>
		<groupId>junit</groupId>
		<artifactId>junit</artifactId>
		<version>4.0</version>
		<scope>test</scope>
	</dependency>		
	
	<dependency>
		<groupId>com.veeja.maven</groupId>
		<artifactId>HelloMaven</artifactId>
		<version>0.0.1-SNAPSHOT</version>
		<scope>compile</scope>
	</dependency>
</dependencies>

發現有一個<scope>的子標籤,這就是指的依賴的範圍。
依賴的範圍常用的三個取值爲compiletestprovided三個。

① 從項目結構的角度理解compile和test的區別

在這裏插入圖片描述
結合具體例子:
對於HelloFriend來說,HelloMaven就是服務於主程序的,junit是服務於測試程序的。
HelloFriend主程序需要 HelloMaven是非常明顯的,測試程序由於要調用主程序所以也需要HelloMaven,所以compile範圍依賴對主程序和測試程序都應該有效。
HelloFriend的測試程序部分需要junit也是非常明顯的,而主程序是不需要的,所以test範圍依賴僅僅對於主程序有效。

② 從開發和運行這兩個不同階段理解 compile 和 provided 的區別

在這裏插入圖片描述
在這裏插入圖片描述

③ 有效性總結

在這裏插入圖片描述
[1]compile範圍依賴

  • 對主程序是否有效:有效
  • 對測試程序是否有效:有效
  • 是否參與打包:參與
  • 是否參與部署:參與
  • 典型例子: spring-core

[2]test範圍依賴

  • 對主程序是否有效:無效
  • 對測試程序是否有效:有效
  • 是否參與打包:不參與
  • 是否參與部署:不參與
  • 典型例子: junit

[3]provided範圍依賴

  • 對主程序是否有效:有效
  • 對測試程序是否有效:有效
  • 是否參與打包:不參與
  • 是否參與部署:不參與
  • 典型例子: servlet-apijar

關於依賴的其他幾個特點,我們將在後面進行介紹。

四、Maven的生命週期

1. 什麼是生命週期?

各個構建環節的執行順序不能打亂,必須按照既定的正確的順序來執行。
Maven的核心程序中定義了抽象的生命週期,生命週期中各個階段的具體任務是由插件來完成的。

Maven 生命週期定義了各個構建環節的執行順序,有了這個清單,Maven 就可以自動化的執行構建命 令了。

Maven 有三套相互獨立的生命週期,分別是:

  1. Clean Lifecycle 在進行真正的構建之前進行一些清理工作。
  2. Default Lifecycle 構建的核心部分,編譯,測試,打包,安裝,部署等等。
  3. Site Lifecycle 生成項目報告,站點,發佈站點。

它們是相互獨立的,你可以僅僅調用 clean 來清理工作目錄,僅僅調用 site 來生成站點。當然你也可以 直接運行 mvn clean install site 運行所有這三套生命週期。

每套生命週期都由一組階段(Phase)組成,我們平時在命令行輸入的命令總會對應於一個特定的階段。比 如,運行 mvn clean,這個 clean 是 Clean 生命週期的一個階段。有 Clean 生命週期,也有 clean 階段。

2. Clean生命週期

Clean 生命週期一共包含了三個階段:
①pre-clean 執行一些需要在 clean 之前完成的工作
②clean 移除所有上一次構建生成的文件
③post-clean 執行一些需要在 clean 之後立刻完成的工作

3. Site生命週期

①pre-site 執行一些需要在生成站點文檔之前完成的工作
②site 生成項目的站點文檔
③post-site 執行一些需要在生成站點文檔之後完成的工作,並且爲部署做準備
④site-deploy 將生成的站點文檔部署到特定的服務器上

這裏經常用到的是 site 階段和 site-deploy 階段,用以生成和發佈 Maven 站點,這可是 Maven 相當強大 的功能,Manager 比較喜歡,文檔及統計數據自動生成,很好看。

4. Default生命週期

Default 生命週期是 Maven 生命週期中最重要的一個,絕大部分工作都發生在這個生命週期中。這裏, 只解釋一些比較重要和常用的階段:
validate
generate-sources
process-sources
generate-resources
process-resources複製並處理資源文件,至目標目錄,準備打包。
compile編譯項目的源代碼。
process-classes
generate-test-sources
process-test-sources
generate-test-resources
process-test-resources複製並處理資源文件,至目標測試目錄。
test-compile編譯測試源代碼。
process-test-classes test 使用合適的單元測試框架運行測試。這些測試代碼不會被打包或部署。
prepare-package package 接受編譯好的代碼,打包成可發佈的格式,如 JAR。
pre-integration-test
integration-test
post-integration-test
verify install將包安裝至本地倉庫,以讓其它項目依賴。
deploy 將最終的包複製到遠程的倉庫,以讓其它開發人員與項目共享或部署到服務器上運行。

5. 生命週期與自動化構建

運行任何一個階段的時候,它前面的所有階段都會被運行,例如我們運行 mvn install 的時候,代碼會 被編譯,測試,打包。這就是 Maven 爲什麼能夠自動執行構建過程的各個環節的原因。此外,Maven 的插 件機制是完全依賴 Maven 的生命週期的,因此理解生命週期至關重要。

五、插件和目標

Maven 的核心僅僅定義了抽象的生命週期,具體的任務都是交由插件完成的。
每個插件都能實現多個功能,每個功能就是一個插件目標。
Maven 的生命週期與插件目標相互綁定,以完成某個具體的構建任務。
例如:compile 就是插件 maven-compiler-plugin 的一個目標;pre-clean 是插件 maven-clean-plugin 的一個目標。


END.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章