易筋SpringBoot 2.1 | 第三十五篇:實戰Aparche Maven 的核心概念與理論 Maven倉庫管理 從入門到精通

1. Maven 簡介

Apache Maven是一個軟件項目管理和理解工具。基於項目對象模型(Project Object Model,POM)的概念,Maven可以從中央信息管理項目的構建,報告和文檔。

Maven可以管理項目構建的整個生命週期,包括清理(Clean)、編譯(Complie)、打包(Package)、測試(Test)等環節。同事Maven提供了非常豐富的插件,使得構建項目和管理項目變得簡單。構建一個項目所需要的流程如下。

  1. 生成源碼;
  2. 從源碼中生成文檔;
  3. 編譯源碼;
  4. 測試;
  5. 將源碼打包成Jar,運行在服務器、倉庫或其它位置。

Apache Maven已經實現了以上的全部功能,並且只需要相關的命令就可以完成相關的功能。

2. Maven的核心概念

Maven的核心是pom文件,pom文件以xml文件的形式來表示資源,包括一些依賴Jar、插件、構建文件等。Maven的工作過程如下:
在這裏插入圖片描述

  1. 首先讀取pom文件。pom文件是Maven的核心,所有的項目依賴、插件都在pom文件中統一管理。
  2. 下載依賴Jar到本地倉庫。Maven命令執行時,首先會檢查pom文件的依賴Jar,當檢測到本地沒有安裝依賴Jar時,會默認從Maven的中央倉庫下載依賴Jar,中央倉庫地址爲https://repo1.maven.org/maven2/。 依賴Jar下載成功後,會存放在本地倉庫中,如果下載不成功,則該命令執行不會通過。
  3. 執行構建的生命週期。Mave的構建過程會被分解成構建階段和構建目標,它們共同構成了Maven的生命週期。
  4. 執行構建插件。插件可以更方便地執行構建的各個階段,也可以用插件實現一些額外的功能。目前Maven有非常豐富的插件,如果需要,你也可以自己實現Maven插件。

3. Maven構建項目的生命週期

在Maven工程中,已經默認定義了構建工程的生命週期,不需要額外引用其它的插件,因爲Maven本身已經集成了這些插件。默認的生命週期包括了23個階段。

階段 描述
validate 驗證工程的完整性
initialize 初始化
generate-sources 生成源碼
process-sources 處理源碼
generate-resources 生成所有源碼
process-resources 處理所有源碼
compile 編譯
process-classes 處理class文件
generate-test-sources 生成測試源碼
process-test-sources 處理測試源碼
generate-test-resources 生成所有測試源碼
process-test-resources 處理所有測試源碼
test-compile 測試編譯
process-test-classes 處理測試class文件
test 測試
prepare-package 預打包
package 打包(如Jar、War)
pre-integration-test 預集成測試
integration-test 集成測試
post-integration-test 完成集成測試
verify 驗證
install 安裝到本地倉庫
deploy 提交到遠程倉庫

4. 常用的Maven命令

  1. mvn clean刪除工程的target目錄下的所有文件。
  2. mvn package將工程打包(如Jar、War)
    mvn package命令執行過程包括以下6個階段:
    2.1 驗證
    2.2 編譯代碼
    2.3 處理代碼
    2.4 生成資源文件
    2.5 打包(如Jar、War)
    2.6 測試
  3. mvn package -Dmaven.test.skip=true 打包時跳過測試。
  4. mvn compile 編譯工程代碼,不打包。
  5. mvn install 命令包含了 mvn package 的所有過程,並且將生成的包安裝到本地倉庫。執行mvn install 命令,可以看到終端輸出的日誌,經過了與mvn package 相同的階段,最後將Jar包安裝到本地倉庫。
  6. mvn spring-boot:run 使用spring-boot插件,啓動Spring Boot工程。該命令執行時先檢查Spring Boot工程源碼是否編譯,如果工程源碼沒有編譯,則先編譯;如果編譯了;則啓動工程。
  7. mvn test 測試;
  8. mvn idea:idea 生成idea項目
  9. mvn jar:jar 只打Jar包
  10. mvn validate 檢驗資源是否可用。

5. Maven 安裝

Maven可作爲zip文件從https://maven.apache.org/download.cgi下載。僅需要二進制文件,因此請查找指向apache-maven- {version} -bin.zipapache-maven- {version} -bin.tar.gz的鏈接。

下載zip文件後,將其解壓縮到計算機上。然後將bin文件夾添加到您的路徑。
筆者是Mac OS, 並且用myzsh
先cd到配置文件

$ vim ~/.zshrc
// 系統默認是 bash
//$ vim ~/.bash_profile

筆者配置信息如下

# JAVA
export JAVA_HOME="$(/usr/libexec/java_home -v 1.8)"
export MAVEN_HOME="/Users/zgpeace/opt/apache-maven-3.5.4"
export SPRING_HOME="/Users/zgpeace/opt/spring-2.1.1.RELEASE"
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$SPRING_HOME/bin:$PATH

要測試Maven安裝,請從命令行運行mvn:

mvn -v

如果一切順利,應該向您提供有關Maven安裝的一些信息。它看起來與以下內容相似(儘管可能略有不同):

mvn -v
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-18T02:33:14+08:00)
Maven home: /Users/zgpeace/opt/apache-maven-3.5.4
Java version: 1.8.0_172, vendor: Oracle Corporation, runtime: /Library/Java/JavaVirtualMachines/jdk1.8.0_172.jdk/Contents/Home/jre
Default locale: en_CN, platform encoding: UTF-8
OS name: "mac os x", version: "10.15.2", arch: "x86_64", family: "mac"

恭喜你!您現在已經安裝了Maven。

信息:您可能想考慮使用Maven包裝器來隔離開發人員,使其避免擁有正確版本的Maven或完全安裝它。從Spring Initializr下載的項目都包含包裝器。它以腳本的形式顯示mvnw在項目的頂層,代替mvn

6. 創建項目

6.1 創建一個Maven項目

在這裏插入圖片描述

GroupId: com.zgpeace.maven
ArtificatId: HelloMaven
Version: 0.1.0

在這裏插入圖片描述

6.2 創建相關類

創建文件目錄結構如下

└── src
    └── main
        └── java
            └── hello

創建類src/main/java/hello/Greeter.java

package hello;

public class Greeter {
  public String sayHello() {
    return "Hello world!";
  }
}

創建類src/main/java/hello/HelloWorld.java

package hello;

public class HelloWorld {
  public static void main(String[] args) {
    Greeter greeter = new Greeter();
    System.out.println(greeter.sayHello());
  }
}

6.3 編輯pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<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.zgpeace.maven</groupId>
    <artifactId>HelloMaven</artifactId>
    <packaging>jar</packaging>
    <version>0.1.0</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>hello.HelloWorld</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    
</project>

除了可選擇 <packaging>元素之外,這是構建Java項目所需的最簡單的pom.xml文件。它包括以下項目配置的詳細信息:

  • <modelVersion>。POM模型版本(始終爲4.0.0)。
  • <groupId>。項目所屬的組或組織。通常表示爲反向域名。
  • <artifactId>。要賦予項目的庫工件的名稱(例如,其JAR或WAR文件的名稱)。
  • <version>。正在構建的項目的版本。
  • <packaging>-如何打包項目。對於JAR文件打包,默認爲“ jar”。使用“ war”進行WAR文件打包。

在選擇版本控制方案時,Spring建議使用語義版本控制方法。
至此,您已定義了一個最小但功能強大的Maven項目。

6.4 構建Java代碼

Maven現在準備構建該項目。您現在可以使用Maven執行幾個構建生命週期目標,包括編譯項目代碼,創建庫包(例如JAR文件)以及在本地Maven依賴項存儲庫中安裝庫的目標。

要嘗試構建,請在命令行中發出以下命令:

mvn compile

這將運行Maven,告訴它執行編譯目標。完成後,您應該在target / classes目錄中找到已編譯的.class文件。

由於您不太可能希望直接分發或使用.class文件,因此您可能需要運行程序包目標:

mvn package

該包裝目標將編譯Java代碼,運行任何測試,並通過在內部的JAR文件將代碼打包了完成目標目錄。JAR文件的名稱將基於項目的<artifactId><version>。例如,給定以前的最小pom.xml文件,則JAR文件將命名爲HelloMaven-0.1.0.jar

要執行JAR文件,請運行:

java -jar target/HelloMaven-0.1.0.jar 

如果將值<packaging>從“ jar”更改爲“ war”,則結果將是目標目錄中的WAR文件而不是JAR文件。
Maven還維護本地計算機上的依賴項存儲庫(通常在主目錄中的.m2 / repository目錄中),以快速訪問項目依賴項。如果要將項目的JAR文件安裝到該本地存儲庫,則應調用install目標:

mvn install

可以切換到本地倉庫,看到一件安裝該項目:

$ cd $HOME 
$ cd .m2/repository/com/zgpeace/maven
$ ls 
HelloMaven

可以看到本地參考目錄結構如下:
在這裏插入圖片描述

在安裝目標將編譯,測試和打包項目的代碼,然後將其複製到本地依賴性庫,準備好另一個項目中引用它作爲一個依賴。

說到依賴,現在是時候在Maven構建中聲明依賴了。

6.5 聲明依賴

簡單的Hello World示例是完全獨立的,並且不依賴於任何其他庫。但是,大多數應用程序都依賴於外部庫來處理常見和複雜的功能。

例如,假設除了說“ Hello World!”外,您還希望應用程序打印當前日期和時間。雖然可以使用本機Java庫中的日期和時間工具,但可以使用Joda Time庫使事情變得更有趣。

首先,將HelloWorld.java更改如下:

package hello;

import org.joda.time.LocalTime;

public class HelloWorld {
  public static void main(String[] args) {
    LocalTime currentTime = new LocalTime();
    System.out.println("The current local time is: " + currentTime);
    Greeter greeter = new Greeter();
    System.out.println(greeter.sayHello());
  }
}

這裏HelloWorld使用Joda Time的LocalTime類來獲取並打印當前時間。

如果您現在要運行mvn compile以構建項目,則構建將失敗,因爲您尚未在構建中將Joda Time聲明爲編譯依賴項。您可以通過將以下行添加到pom.xml(在元素內)來解決此問題:

	<dependencies>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.5</version>
        </dependency>
    </dependencies>

XML塊聲明瞭項目的依賴項列表。具體來說,它聲明瞭Joda Time庫的單個依賴關係。在<dependency>元素內,依賴關係座標由三個子元素定義:

  • <groupId> -依賴關係所屬的組或組織。
  • <artifactId> -所需的庫。
  • <version> -所需的特定版本的庫。

默認情況下,所有依賴項的作用域都作爲compile依賴項。也就是說,它們應該在編譯時可用(如果您正在構建WAR文件,包括在WAR/ WEB-INF / libs文件夾中)。此外,您可以指定一個<scope>元素來指​​定以下範圍之一:

  • provided -編譯項目代碼所需的依賴關係,但將在運行時由運行代碼的容器(例如Java Servlet API)提供。
  • test -用於編譯和運行測試的依賴性,但對於構​​建或運行項目的運行時代碼不是必需的。

現在,如果您運行mvn compilemvn package,則Maven應該從Maven Central存儲庫中解決Joda Time依賴關係,並且構建將成功。

6.6 編寫測試

首先在測試範圍內將JUnit作爲對pom.xml的依賴項添加:

<dependency>
	<groupId>junit</groupId>
	<artifactId>junit</artifactId>
	<version>4.12</version>
	<scope>test</scope>
</dependency>

然後創建一個如下的測試用例:

src/test/java/hello/GreeterTest.java

package hello;

import static org.hamcrest.CoreMatchers.containsString;
import static org.junit.Assert.*;

import org.junit.Test;

public class GreeterTest {

  private Greeter greeter = new Greeter();

  @Test
  public void greeterSaysHello() {
    assertThat(greeter.sayHello(), containsString("Hello"));
  }

}

Maven使用名爲“ surefire”的插件來運行單元測試。此插件的默認配置將編譯並運行src/test/java名稱匹配的所有類*Test。您可以像這樣在命令行上運行測試

MVN測試
或只使用mvn install上面已經顯示的步驟(有一個生命週期定義,其中“測試”作爲“安裝”的一個階段包含在內)。

這是完成的pom.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<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.zgpeace.maven</groupId>
    <artifactId>HelloMaven</artifactId>
    <packaging>jar</packaging>
    <version>0.1.0</version>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>2.10.5</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.1</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>hello.HelloWorld</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    
</project>

7. 總結

恭喜你!您已經創建了一個簡單而有效的Maven項目定義來構建Java項目。

也可以看看
使用Gradle構建Java項目

代碼下載:
https://github.com/zgpeace/Spring-Boot2.1

參考

https://spring.io/guides/gs/maven/

http://maven.apache.org/

https://www.jianshu.com/p/6bc2c4e9142c

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