玩轉Maven之使用入門

前言

說到Maven的入門使用,其實是特別簡單的,如果只是說就是能使用,會使用Maven,也許只要短短的一兩個小時就OK了,不需要去理解Maven的那些概念,而這篇文章就是要教會你會使用Maven,而整個系列則是要讓你明白整個Maven。這篇文章就是如此,僅僅就是告訴你怎麼用Maven,僅此而已,會用是學習整個系列的前提。

編寫POM

就像composer的composer.json、Make的makefile文件一樣,Maven項目的核心是pom.xml文件。POM(Project Object Model,項目對象模型)定義了項目的基本信息,用於描述項目如何構建,聲明項目依賴,等等。

現在我們不借助任何其它命令和IDE,來創建一個Maven項目。

首先,編寫pom.xml文件。還是按照老規矩,從一個Hello World項目進行演示。以下就是創建項目的POM文件。

<?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.jellythink.HelloWorld</groupId>
  <artifactId>hello-world</artifactId>
  <version>1.0-SNAPSHOT</version>

  <name>hello-world</name>
  
  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>
</project>

對於POM文件,現在細說一下。

  • 代碼的第一行是XML頭,指定了該xml文檔的版本和編碼方式。緊接着是project元素,project是所有pom.xml的根元素,它還聲明瞭一些POM相關的命名空間及xsd元素;

  • 根元素下的第一個子元素modelVersion指定了當前POM模型的版本,對於Maven 2和Maven 3來說,它只能是4.0.0;

  • 接下來就是groupIdartifactIdversion了,這三個是上述代碼三個元素。這三個元素定義了一個項目的基本座標,在Maven的世界裏,所有的jar和war都是基於座標進行區分的,會面的文章還會細說座標;

  • groupId定義了項目屬於哪個組,這個組往往和項目所在的組織或公司存在關聯,一般是使用組織或公司的域名;比如上面的groupIdcom.jellythink.HelloWorld,其中com.jellythink就是我的網站域名倒過來寫的,而HelloWorld則是整個項目的名稱;

  • artifactId定義了當前Maven項目在組中唯一的ID,一般一個大項目組下面可能會包含多個子項目或子模塊,而這個artifactId就是子項目或者子模塊的名稱;

  • version指定了這個項目當前的版本,後面的文章還會細說Maven中版本的含義;

  • name元素聲明瞭一個對於用戶更爲友好的項目名稱,方便後期的管理;

  • properties指定了Maven的一些重要屬性,後續還會重點說這個屬性的一些配置。

創建完pom.xml文件後,接下來就是創建代碼文件了。在Maven中,有這樣的一個約定,項目主代碼都位於src/main/java目錄,項目測試代碼都位於src/test/java目錄;接下來我們先按照這個約定分別創建目錄,然後在代碼目錄創建com/jellythink/HelloWorld/App.java文件;在測試目錄創建com/jellythink/HelloWorld/AppTest.java文件。

還是老規矩,我們在App.java中打印Hello World!,代碼如下:

public class App {
    public String sayHello() {
        return "Hello World";
    }

    public static void main( String[] args ) {
        System.out.println(new App().sayHello());
    }
}

同理,對於AppTest.java中編寫以下單元測試代碼:

public class AppTest {
    @Test
    public void testSayHello() {
        App app = new App();
        String result = app.sayHello();
        assertEquals("Hello World", result);
    }
}

在Java中,我們進行單元測試時,基本上都是使用的JUnit,要使用JUnit這個包,我們就需要引入這個依賴包,此時,我們就需要在pom.xml中添加以下依賴內容:

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

代碼中添加了dependencies元素,該元素下可以包含多個dependency元素以聲明項目的依賴。前面也說過,groupIdartifactIdversion是任何一個Maven項目最基本的座標,JUnit也不例外;scope表示依賴範圍,後續的文章還會細說這個依賴和測試相關的內容。

編譯和測試

萬事俱備,只欠東風。接下來我們編譯和測試。

搞定代碼後,使用Maven進行編譯,在項目根目錄下運行mvn clean compile命令。執行輸出如下圖所示:

clean告訴Maven清理輸出目錄target,compile告訴Maven編譯項目主代碼。從輸出中看到Maven首先執行了clean:clean任務,刪除target目錄。默認情況下,Maven構建的所有輸出都在target目錄中;接着執行resources:resources任務;最後執行compiler:compile任務,將項目主代碼編譯至target/classes目錄。

上面說到的clean:cleanresources:resourcescompiler:compile都對應了Maven的生命週期及插件,這個在後面還會有專題文章細說。

編譯完成後,我們一般都會運行測試代碼進行單元測試,雖然很多情況下,我們並沒有這麼做,但是我還是建議大家通過Maven做一些自動化的單元測試。

測試用例編寫完畢之後就可以調用Maven執行測試,運行mvn clean test命令,輸出如下:

從輸出可以看到,Maven依次執行了clean:cleanresources:resourcescompiler:compileresources:testResourcescompiler:testCompilesurefire:test。現階段,我們需要明白這是Maven的生命週期的一個特性,這個生命週期後續還會細說。

到此,編譯和測試均通過了,接着我們進行應用打包和運行。

打包和運行

打包就是將我們編寫的應用打成JAR包或者WAR包。在我們的HelloWorld示例程序POM中,並沒有指定打包類型,Maven則默認打包成JAR包。我們執行mvn clean package命令就可以完成打包。mvn clean package命令的輸出如下:

可以看到,Maven在打包之前會執行編譯、測試等操作,最後通過jar:jar任務負責打包。實際上就是jar插件的jar目標將項目主代碼打包成一個名爲hello-world-1.0-SNAPSHOT.jar的文件,這個最終生成的包會保存在target目錄下,它是根據artifact-version.jar規則進行命名的;當然了,我們可以使用finalName屬性來自定義該文件的名稱。

到現在,我們得到了這個JAR包,如果別的項目要引用這個JAR包時,我們將這個JAR包複製到其它項目的classpath中就OK了。但是這樣拷貝就違背了我們當初想要自動解決依賴的問題,所以如何才能讓其它的Maven項目直接引用這個JAR包呢?我們需要執行mvn clean install命令。

從輸出可以看到,在打包之後,又執行了安裝任務install:install,最後將項目輸出的JAR包安裝到了Maven本地倉庫中,我們可以在本地的倉庫文件夾中能看到這個示例項目的pom和jar包。

到目前爲止,通過這個示例項目體驗了mvn clean compilemvn clean testmvn clean packagemvn clean install。執行test之前會先執行compile的,執行package之前會先執行test的,而類似地,install之前會執行package。我們可以在任何一個Maven項目中執行這些命令。

最後,不要忘了,我們生成的JAR包是有main方法的,也就是說這個JAR包是可以單獨運行的;但是,由於帶有main方法的類信息沒有添加到manifest中,所以默認打包生成的jar是不能夠直接運行的(使用jd-gui打開jar文件中的META-INF/MANIFEST.MF文件,將無法看到Main-Class一行)。爲了生成可執行jar文件,需要藉助Apache Maven Shade Plugin來完成,我們需要在pom.xml文件中以下插件配置:

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

接下來,我們再執行mvn clean install命令,待構建完成之後在target目錄下可以看到hello-world-1.0-SNAPSHOT.jar和original-hello-world-1.0-SNAPSHOT.jar,前面的是帶有Main-Class信息的可運行jar,後者是原始的jar。我們執行以下命令:

java -jar hello-world-1.0-SNAPSHOT.jar

就可以正常執行。

使用Archetype生成項目骨架

上面非常詳細的總結了如何全手動的創建一個Maven工程。通過上面的總結,我們大體可以總結以下幾步:

  • 在項目根目錄創建pom.xml文件;

  • 創建src/main/java目錄,並在該目錄開發項目主代碼;

  • 創建src/test/java目錄,並在該目錄開發項目測試代碼;

上面的三步我們成爲Maven項目的骨架,也就是現在常說的“腳手架”。如果我們每創建一個Maven項目都需要把上面的步驟執行一次,確實很麻煩,那怎麼辦?程序就是解放人工的,讓人來偷懶的。所以,在Maven中,我們可以通過Archetype生成項目骨架,將上面的步驟流程化。比如,現在我們要創建一個Maven項目,我們只需要輸入以下命令就OK了。

mvn archetype:generate

執行這個命令後,後看到很多輸出,有很多可用的Archetype供我們選擇,每一個Archetype前面都會對應有一個編號,我們根據我們的需要,選擇我們對應的骨架來創建項目就好了。然後再按照提示,輸出新項目的groupId、artifactId、version和包名package,一個Maven項目就創建成功了。

我們在運行mvn archetype:generate時,實際上是在運行maven-archetype-plugin插件。

總結

到此,這篇關於Maven的初級入門文章就到此總結完畢,這篇文章的知識點比較多,而且還很雜,如果看的有點不是很懂,也沒有關係,後續的文章都會對這些你不懂的地方,你不熟悉的地方在進行深入的剖析和總結。當然了,也希望大家能通過這篇文章對Maven的使用有一個整體的認識,至少沒有後續的文章,通過這篇文章,你也應該知道怎麼使用Maven了,不是嗎?

這一夜,深深的自責中......

往期精彩回顧

1、《玩轉Maven之安裝與配置

書籍推薦


人生是個圓,有的人走了一輩子也沒有走出命運畫出的圓圈,其實,圓上的每一個點都有一條騰飛的切線。

玩代碼、玩技術

長按識別二維碼,關注“果凍想”

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