Maven 快速入門
1.Maven 全面概述
Apache Maven 是一種軟件項目管理和理解工具。基于項目對象模型的概念(POM
),Maven
可以從中央信息中管理項目的構建,報告和文檔。
2.Maven 基本功能
因此實際上 Maven
的基本功能就是作為 Java
的項目包管理器,可以快速配置項目的依賴并且進行版本配置管理,其配置的理念是基于項目對象模型 project object model
。具體來說,Maven
回使用 pom.xml
這種項目描述文檔來描述一個項目以及對應的依賴。
然后再基于這份文檔,使用 maven
的命令行工具進行依賴管理即可,類似 Cpp
的 Vcpkg
工具、Python
的 Pip
工具…
3.Maven 使用教程
3.1.下載安裝
在安裝之前,由于 Maven
是 Java
工具,您必須先保證下載好 Java
才能繼續安裝 Maven
。
# 下載安裝
# 檢查 Java 的版本
$ java --version
openjdk 17.0.13 2024-10-15
OpenJDK Runtime Environment (build 17.0.13+11-Ubuntu-2ubuntu124.04)
OpenJDK 64-Bit Server VM (build 17.0.13+11-Ubuntu-2ubuntu124.04, mixed mode, sharing)# 拉取二進制壓縮包并且解壓查看
$ wget https://dlcdn.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.zip
$ unzip apache-maven-3.9.9-bin.zip$ cd apache-maven-3.9.9/
$ ls
bin boot conf lib LICENSE NOTICE README.txt# 把二進制可執行文件目錄添加到 PATH 環境變量中
$ vim ~/.bashrc && cat ~/.bashrc
# ...
$PATH=<maven_path>:$PATH # 請將 maven# 檢查是否安裝成功
$ mvn -v
Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: /home/ljp/tools/maven/apache-maven-3.9.9
Java version: 17.0.13, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
Default locale: zh_CN, platform encoding: UTF-8
OS name: "linux", version: "6.8.0-51-generic", arch: "amd64", family: "unix"
3.2.可選配置
-
MAVEN_ARGS 環境變量(操作 MVC 的參數) 從
Maven 3.9.0
開始,此變量包含傳遞給Maven
的參數,優先于用戶的命令行參數。例如,可以通過-B -V checkstyle:checkstyle
定義選項和目標。其中-B
表示跳過交互式提示,-V
表示顯示 Maven 的版本信息,checkstyle:checkstyle
是一個目標任務,表示運行 Checkstyle 插件進行代碼檢查。 -
MAVEN_OPTS 環境變量(操作 JVM 的參數) 該變量包含用于啟動
Maven
所需的JVM
參數,可以用來向JVM
提供額外的選項。例如,JVM
的內存設置可以通過-Xms256m -Xmx512m
來定義。 -
settings.xml 文件
settings.xml
用于存儲跨項目的Maven
配置,通常存儲在兩個目錄中- 用戶級別配置目錄
$USER_HOME/.m2/settings.xml
- 全局級別配置目錄
$MAVEN_HOME/conf/settings.xml
您可以稍微查看一下全局級別配置文件,稍微了解一下,當存在用戶級別配置文件時,就會優先使用用戶級別配置文件。
<!-- settings.xml --> <?xml version="1.0" encoding="UTF-8"?><settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd"><!-- 配置本地倉庫| 配置 Maven 下載好后的依賴存儲目錄|| 默認值: ${user.home}/.m2/repository<localRepository>/path/to/local/repo</localRepository>--><!-- 配置交互模式| 配置 Maven 是否運行過程和用戶交互| | 默認值: true<interactiveMode>true</interactiveMode>--><!-- 配置離線模式| 配置 Maven 是否直接在本地獲取依賴|| 默認值: false<offline>false</offline>--><!-- 配置插件小組| 配置 Maven 配置插件的查詢地址標識|| 默認值: 無默認值|--><pluginGroups><!-- pluginGroup<pluginGroup>com.your.plugins</pluginGroup>--></pluginGroups><!-- 配置代理服務| 配置 Maven 訪問外部倉庫時代理服務|| 默認值: 無默認值|--><proxies><!-- proxy<proxy><id>optional</id><active>true</active><protocol>http</protocol><username>proxyuser</username><password>proxypass</password><host>proxy.host.net</host><port>80</port><nonProxyHosts>local.net|some.host.com</nonProxyHosts></proxy>--></proxies><!-- 配置本機認證| 配置 Maven 訪問遠端倉庫的認證信息|--><servers><!-- server 使用密碼<server><id>deploymentRepo</id><username>repouser</username><password>repopwd</password></server>--><!-- server 使用密鑰<server><id>siteServer</id><privateKey>/path/to/private/key</privateKey><passphrase>optional; leave empty if not used.</passphrase></server>--></servers><!-- 配置鏡像地址| 配置 Maven 鏡像地址提高下載速度||--><mirrors><!-- mirror<mirror><id>mirrorId</id><mirrorOf>repositoryId</mirrorOf><name>Human Readable Name for this Mirror.</name><url>http://my.repository.com/repo/path</url></mirror>--><mirror><id>maven-default-http-blocker</id><mirrorOf>external:http:*</mirrorOf><name>Pseudo repository to mirror external repositories initially using HTTP.</name><url>http://0.0.0.0/</url><blocked>true</blocked></mirror></mirrors><!-- 配置特定設置| 配置 Maven 根據標識激活特定設置| 例如使用 -D env=dev 就可以觸發 name=env value=dev 所對應的 activation 設置||--><profiles><!-- profile<profile><id>env-dev</id><activation><property><name>target-env</name><value>dev</value></property></activation><properties><tomcatPath>/path/to/tomcat/instance</tomcatPath></properties></profile>--><!-- profile<profile><id>jdk-1.4</id><activation><jdk>1.4</jdk></activation><repositories><repository><id>jdk14</id><name>Repository for JDK 1.4 builds</name><url>http://www.myhost.com/maven/jdk14</url><layout>default</layout><snapshotPolicy>always</snapshotPolicy></repository></repositories></profile>--></profiles><!-- activeProfiles| 配置 Maven 平時默認激活特定設置|<activeProfiles><activeProfile>填寫上面定義的 value</activeProfile><activeProfile>可以繼續填寫...</activeProfile></activeProfiles>--> </settings>
- 用戶級別配置目錄
-
.mvn 目錄 位于
Maven
項目的頂級目錄中,一般包含三個文件-
.mvn/maven.config
從Maven 3.3.1+
開始,可以通過.mvn/maven.config
文件簡化Maven
命令行參數的設置(每個參數最好直接單獨一行),這樣就不再需要使用MAVEN_ARGS
-
.mvn/jvm.config
從Maven 3.3.1+
開始,可以通過.mvn/jvm.config
文件為每個項目定義JVM
配置(每個參數最好直接單獨一行),這樣就不再需要使用MAVEN_OPTS
-
.mvn/extensions.xml
過去的做法(直到Maven 3.2.5
)是創建一個JAR
文件并將其手動放入${MAVEN_HOME}/lib/ext
目錄中,或者通過mvn -Dmaven.ext.class.path=extension.jar
命令行選項來加載擴展。現在可以通過定義.mvn/extensions.xml
,一般實際開發中用來拓展Maven
核心功能的,和settings.xml
作用還是有很大不同的,不要混淆一談,有需要了解一下即可(修改后可用mvn help:effective-settings
進行配置檢查)。
-
[!IMPORTANT]
補充:不過一般情況下,我們無需改動以上的環境變量和配置文件。
- 對于環境變量一般使用
.mvn/maven.config
和.mvn/jvm.config
來替代,這樣每一個項目配置起來比較靈活- 一般也用不到
.mvn/extensions.xml
這種需要拓展Maven
功能。- 而對于經過正常魔法手段的網絡環境下,一般也無需配置
settings.xml
,使用默認的即可,如果需要修改,一般也只有以下三個個人開發者需求(最好只修改用戶級別的settings.xml
配置文件)
- 可能需要改動依賴存儲的目錄,以避免系統磁盤占用過多,只需要改動
<localRepository>
標簽即可- 可能需要改動網絡代理的配置,以使用魔法陣來健康上網,只需要改動
<proxy>
標簽即可- 可能需要配置一些插件,后續使用
Maven
管理的Java
項目(這里指專門開發Maven
插件的Java
項目)開發完畢后進行mvn install
后會把插件安裝到本地倉庫~/.m2/repository/
中,此時需要使用這里面的插件標簽來標識該插件以簡化命令行的使用因此總結來說,使用
.mvn/maven.config
、.mvn/jvm.config
、settings.xml
的概率是最大的。另外,一般開發環境使用
mvn
的命令行多一些,因為命令行的可選參數優先級最高,可以覆蓋.mvn/maven.config
、.mvn/jvm.config
這兩個配置文件。而測試環境、生產環境一般使用.mvn/maven.config
、.mvn/jvm.config
這兩個配置文件會多一些,因為更加方便。
3.3.常用指令
這里先列出并且大概說下 mvn
工具的常見指令。
mvn [options] [<goal(s)>] [<phase(s)>]
使用通用的options
可選參數,比如-Dproperty=value
(設置屬性)、-X
(啟用調試模式)等goal
具體目標,通常是指執行某些自定插件phase
生命階段,通常是指生命周期內的階段
mvn -h
可以查詢相關的指令幫助mvn verify
最為典型的指令調用
[!IMPORTANT]
補充:
Maven
生命周期是一套預定義的phases, 構建階段
,確保項目按照既定順序進行構建。Maven
有3
個Lifecycle, 生命周期
,分別是
clean
(“清理” 生命周期),包含多個階段。本生命周期內,在執行某個階段時,會自動執行該階段前面的所有階段
pre-clean
:執行清理前的操作clean
:刪除target/
目錄post-clean
:執行清理后的操作default
(“構建” 生命周期),包含多個階段。本生命周期內,在執行某個階段時,會自動執行該階段前面的所有階段
validate
驗證項目是否正確,并檢查pom.xml
配置compile
編譯源碼(src/main/java
)到target/classes
test
運行單元測試(基于src/test/java
),不過有時可以使用mvn clean package -DskipTests
跳過測試階段package
將編譯后的代碼打包(如jar
、war
)verify
運行集成測試,確保打包的應用正常install
安裝jar
/war
到本地倉庫下(~/.m2/repository/
),一般會安裝一些項目,比如自定義的插件項目和其他的服務項目,以方便別的項目進行本地依賴deploy
發布jar
/war
到遠程倉庫(如Nexus
)site
(“文檔” 生命周期),包含多個階段。本生命周期內,在執行某個階段時,會自動執行該階段前面的所有階段
pre-site
:執行文檔生成前的任務site
:生成 HTML 文檔post-site
:執行文檔生成后的任務site-deploy
:發布站點到服務器而在
pom.xml
中的plugin, 插件
標簽可以綁定到特定階段,擴展構建過程。也就是說,您可以在Maven
的構建過程中,插入額外的任務(例如代碼生成、代碼檢查、打包方式自定義等),以干預生命周期的行為。
3.4.代碼實踐
3.4.1.編寫普通 Maven 項目
3.4.1.1.創建項目
# 創建項目
$ mvn archetype:generate -DgroupId=com.work -DartifactId=work-maven-test -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=1.5 -DinteractiveMode=false# archetype:generate 是插件中定義的目標, 用來基于模板生成新項目結構
# -DgroupId 指定本項目的 groupId, 就是公司域名的倒寫
# -DartifactId 指定本項目的 artifactId, 就是本項目的具體名稱
# -DarchetypeArtifactId 指定本項目的 archetypeArtifactId, 就是生成本項目所使用的項目模板
# -DarchetypeVersion=1.5 指定本項目的 archetypeVersion, 就是所使用的 Archetype 模板的版本
# -DinteractiveMode=false 表示禁用交互模式, 避免用戶手動輸入, 轉為讓 Maven 自動進行配置填充參數
# 以下是上述指令的運行結果...[INFO] Scanning for projects...
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/3.1.0/maven-antrun-plugin-3.1.0.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/3.1.0/maven-antrun-plugin-3.1.0.pom (9.1 kB at 7.6 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/3.1.0/maven-antrun-plugin-3.1.0.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-antrun-plugin/3.1.0/maven-antrun-plugin-3.1.0.jar (41 kB at 74 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/3.7.1/maven-assembly-plugin-3.7.1.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/3.7.1/maven-assembly-plugin-3.7.1.pom (15 kB at 46 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/3.7.1/maven-assembly-plugin-3.7.1.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-assembly-plugin/3.7.1/maven-assembly-plugin-3.7.1.jar (240 kB at 142 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/3.7.0/maven-dependency-plugin-3.7.0.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/3.7.0/maven-dependency-plugin-3.7.0.pom (19 kB at 30 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/3.7.0/maven-dependency-plugin-3.7.0.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-dependency-plugin/3.7.0/maven-dependency-plugin-3.7.0.jar (207 kB at 41 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-release-plugin/3.0.1/maven-release-plugin-3.0.1.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-release-plugin/3.0.1/maven-release-plugin-3.0.1.pom (9.8 kB at 16 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/release/maven-release/3.0.1/maven-release-3.0.1.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/release/maven-release/3.0.1/maven-release-3.0.1.pom (11 kB at 20 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-release-plugin/3.0.1/maven-release-plugin-3.0.1.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-release-plugin/3.0.1/maven-release-plugin-3.0.1.jar (61 kB at 36 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-metadata.xml (14 kB at 26 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/mojo/maven-metadata.xml (21 kB at 11 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-archetype-plugin/maven-metadata.xml (1.0 kB at 3.6 kB/s)
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] >>> archetype:3.3.1:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO]
[INFO] <<< archetype:3.3.1:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO]
[INFO]
[INFO] --- archetype:3.3.1:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
Downloading from central: https://repo.maven.apache.org/maven2/archetype-catalog.xml
Downloaded from central: https://repo.maven.apache.org/maven2/archetype-catalog.xml (16 MB at 18 kB/s)
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Old (1.x) Archetype: maven-archetype-quickstart:1.0
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: basedir, Value: /home/ljp/data/ljp/test
[INFO] Parameter: package, Value: com.work
[INFO] Parameter: groupId, Value: com.work
[INFO] Parameter: artifactId, Value: work-maven-test
[INFO] Parameter: packageName, Value: com.work
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] project created from Old (1.x) Archetype in dir: /home/ljp/data/ljp/test/work-maven-test
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 15:25 min
[INFO] Finished at: 2025-02-11T13:07:47+08:00
[INFO] ------------------------------------------------------------------------
然后查看一下創建好的項目中生成的比較重要的項目文件。
# 查看配置好的項目
$ ls
work-maven-test
$ tree work-maven-test
├── pom.xml
└── src├── main│ └── java│ └── com│ └── work│ └── App.java└── test└── java└── com└── work└── AppTest.java10 directories, 3 files
<!-- pox.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/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.work</groupId><artifactId>work-maven-test</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><name>work-maven-test</name><dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency></dependencies>
</project>
// App.java
package com.work;/*** Hello world!**/
public class App
{public static void main( String[] args ){System.out.println( "Hello World!" );}
}
// AppTest.java
package com.work;import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;/*** Unit test for simple App.*/
public class AppTest extends TestCase
{/*** Create the test case** @param testName name of the test case*/public AppTest( String testName ){super( testName );}/*** @return the suite of tests being tested*/public static Test suite(){return new TestSuite( AppTest.class );}/*** Rigourous Test :-)*/public void testApp(){assertTrue( true );}
}
[!IMPORTANT]
補充:欸,好像上述的結果和我們直接使用
IDEA
中的內置Maven
創建的Java
項目不太一樣,原因是因為使用不同的模板,我們使用的模板適合大部分的Java
項目。
src/main/java
目錄包含項目源代碼,src/test/java
目錄包含測試源,而 pom.xml
文件是項目的項目對象模型,主要用于描述本項目(的依賴情況)。
3.4.1.2.編寫項目
pom.xml
可能看上去有些許復雜,但是我可以幫助您抽絲剝繭,簡化您對該文件的理解難度,因此我對上述的 pom.xml
做了一些修改和注釋,以供您理解和作為模板參考。
<!-- 理解 pox.xml -->
<!--'xmlns=' XML 命名空間'xmlns:xsi' XML Schema 實例命名空間'xsi:schemaLocation=' 指定 XML Schema 位置這些聲明的主要作用是幫助 XML 解析器正確地驗證和處理 Maven POM 文件,確保它符合 Maven 規范。-->
<projectxmlns="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/maven-v4_0_0.xsd"><!-- 指定 Maven 項目對象模型 POM 的版本 --><modelVersion>4.0.0</modelVersion><!-- 定義項目的所屬組織 --><groupId>com.work</groupId><!-- 定義項目的具體名稱 --><artifactId>work-maven-test</artifactId><!-- 指定項目構建的打包類型為 .jar --><packaging>jar</packaging><!-- 定義項目的版本號 --><version>v0.1.0</version><!-- 和 artifactId 的名稱保持一樣即可(這是一個可選字段) --><name>work-maven-test</name><!-- 填寫為本項目制定的官方網址 --><url>https://work-maven-test.work.com</url><!-- 填寫所有依賴項的容器, 在內部填寫一個一個 dependency 標簽 --><url>http://maven.apache.org</url><!-- 填寫依賴的 Java 版本 --><properties><java.version>17</java.version></properties><dependencies><!-- 依賴名稱: 依賴官網/依賴源碼 --><!-- Junit: https://junit.org/junit5/ --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope> <!-- 如果不指定 scope 會默認將依賴設置為 compile 生命階段, 因此設置 scope 本質是確保某些依賴只在某個階段被使用 --></dependency></dependencies>
</project>
我們引入一個依賴到項目中進行實戰,就選擇 Google
開發的 Gson
吧,再次修改 pom.xml
。
<!-- 修改 pom.xml -->
<!--'xmlns=' XML 命名空間'xmlns:xsi' XML Schema 實例命名空間'xsi:schemaLocation=' 指定 XML Schema 位置這些聲明的主要作用是幫助 XML 解析器正確地驗證和處理 Maven POM 文件,確保它符合 Maven 規范。-->
<projectxmlns="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/maven-v4_0_0.xsd"><!-- 指定 Maven 項目對象模型 POM 的版本 --><modelVersion>4.0.0</modelVersion><!-- 定義項目的所屬組織 --><groupId>com.work</groupId><!-- 定義項目的具體名稱 --><artifactId>work-maven-test</artifactId><!-- 指定項目構建的打包類型為 .jar --><packaging>jar</packaging><!-- 定義項目的版本號 --><version>v0.1.0</version><!-- 和 artifactId 的名稱保持一樣即可(這是一個可選字段) --><name>work-maven-test</name><!-- 填寫為本項目制定的官方網址 --><url>https://work-maven-test.work.com</url><!-- 填寫依賴的 Java 版本 --><properties><java.version>17</java.version></properties><!-- 填寫所有依賴項的容器, 在內部填寫一個一個 dependency 標簽 --><dependencies><!-- 依賴名稱: 依賴官網/依賴源碼 --><!-- Junit: https://junit.org/junit5/ --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope> <!-- 如果不指定 scope 會默認將依賴設置為 compile 生命階段, 因此設置 scope 本質是確保某些依賴只在某個階段被使用 --></dependency><!-- Gson: https://github.com/google/gson --><dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.12.1</version></dependency></dependencies>
</project>
然后修改 App.java
文件,在內部使用關于 Gson
的代碼進行依賴測試。
// 修改 App.java
package com.work;import com.google.gson.Gson;public class App {public static void main(String[] args) {// 創建一個對象Person person = new Person("John", 30);// 創建Gson實例Gson gson = new Gson();// 將對象轉換為 JSON 字符串String json = gson.toJson(person);System.out.println("JSON Output: " + json);// 將 JSON 字符串轉換為對象Person personFromJson = gson.fromJson(json, Person.class);System.out.println("Person Name: " + personFromJson.getName());System.out.println("Person Age: " + personFromJson.getAge());}
}class Person {private String name;private int age;public Person(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}
}
然后清理項目,打包得到我們的 jar
包(跳過測試階段),最后看看能不能得到預期的結果。
# 查看執行結果
$ mvn clean package -DskipTests
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.work:work-maven-test >----------------------
[INFO] Building work-maven-test v0.1.0
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
Downloading from central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.12.1/gson-2.12.1.pom
Downloaded from central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.12.1/gson-2.12.1.pom (13 kB at 11 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson-parent/2.12.1/gson-parent-2.12.1.pom
Downloaded from central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson-parent/2.12.1/gson-parent-2.12.1.pom (27 kB at 38 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.36.0/error_prone_annotations-2.36.0.pom
Downloaded from central: https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.36.0/error_prone_annotations-2.36.0.pom (4.3 kB at 17 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.36.0/error_prone_parent-2.36.0.pom
Downloaded from central: https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.36.0/error_prone_parent-2.36.0.pom (16 kB at 58 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.12.1/gson-2.12.1.jar
Downloaded from central: https://repo.maven.apache.org/maven2/com/google/code/gson/gson/2.12.1/gson-2.12.1.jar (286 kB at 384 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.36.0/error_prone_annotations-2.36.0.jar
Downloaded from central: https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.36.0/error_prone_annotations-2.36.0.jar (19 kB at 77 kB/s)
[INFO]
[INFO] --- clean:3.2.0:clean (default-clean) @ work-maven-test ---
[INFO]
[INFO] --- resources:3.3.1:resources (default-resources) @ work-maven-test ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /home/ljp/data/ljp/test/work-maven-test/src/main/resources
[INFO]
[INFO] --- compiler:3.13.0:compile (default-compile) @ work-maven-test ---
[INFO] Recompiling the module because of changed source code.
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file with javac [debug target 1.8] to target/classes
[WARNING] 未與 -source 8 一起設置引導類路徑
[INFO]
[INFO] --- resources:3.3.1:testResources (default-testResources) @ work-maven-test ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /home/ljp/data/ljp/test/work-maven-test/src/test/resources
[INFO]
[INFO] --- compiler:3.13.0:testCompile (default-testCompile) @ work-maven-test ---
[INFO] Recompiling the module because of changed dependency.
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 1 source file with javac [debug target 1.8] to target/test-classes
[WARNING] 未與 -source 8 一起設置引導類路徑
[INFO]
[INFO] --- surefire:3.2.5:test (default-test) @ work-maven-test ---
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/maven-surefire-common/3.2.5/maven-surefire-common-3.2.5.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/maven-surefire-common/3.2.5/maven-surefire-common-3.2.5.jar (308 kB at 640 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-api/3.2.5/surefire-api-3.2.5.jar
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-logger-api/3.2.5/surefire-logger-api-3.2.5.jar
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-api/3.2.5/surefire-extensions-api-3.2.5.jar
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-booter/3.2.5/surefire-booter-3.2.5.jar
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-spi/3.2.5/surefire-extensions-spi-3.2.5.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-logger-api/3.2.5/surefire-logger-api-3.2.5.jar (14 kB at 55 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-common-artifact-filters/3.1.1/maven-common-artifact-filters-3.1.1.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/shared/maven-common-artifact-filters/3.1.1/maven-common-artifact-filters-3.1.1.jar (61 kB at 96 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.15.1/commons-io-2.15.1.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-spi/3.2.5/surefire-extensions-spi-3.2.5.jar (8.2 kB at 9.6 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-shared-utils/3.2.5/surefire-shared-utils-3.2.5.jar
Downloaded from central: https://repo.maven.apache.org/maven2/commons-io/commons-io/2.15.1/commons-io-2.15.1.jar (501 kB at 417 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-api/3.2.5/surefire-api-3.2.5.jar (171 kB at 130 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-booter/3.2.5/surefire-booter-3.2.5.jar (118 kB at 85 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-extensions-api/3.2.5/surefire-extensions-api-3.2.5.jar (26 kB at 12 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/maven/surefire/surefire-shared-utils/3.2.5/surefire-shared-utils-3.2.5.jar (2.4 MB at 1.1 MB/s)
[INFO] Tests are skipped.
[INFO]
[INFO] --- jar:3.4.1:jar (default-jar) @ work-maven-test ---
[INFO] Building jar: /home/ljp/data/ljp/test/work-maven-test/target/work-maven-test-v0.1.0.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 7.012 s
[INFO] Finished at: 2025-02-11T15:36:18+08:00
[INFO] ------------------------------------------------------------------------# 找到上述 Build 成功的 jar 所在地
$ ls
pom.xml src target$ cd target && ls
classes generated-test-sources maven-status work-maven-test-v0.1.0.jar
generated-sources maven-archiver test-classes$ java -jar work-maven-test-v0.1.0.jar
work-maven-test-v0.1.0.jar中沒有主清單屬性
欸怎么回事?沒有主清單屬性其實是因為 work-maven-test-v0.1.0.jar
文件中的 META-INF/MANIFEST.MF
文件在打包的時候沒有指定啟動主類,我們需要自己添加主類位置(或者您使用 jar -xf work-maven-test-v0.1.0.jar
解包后在 META-INF/MANIFEST.MF
中添加 Main-Class: com.example.Main
也是可以的,不過我個人不推薦這么做)。
# 嘗試運行 jar 包
$ java -cp "work-maven-test-v0.1.0.jar" com.work.App
Exception in thread "main" java.lang.NoClassDefFoundError: com/google/gson/Gsonat com.work.App.main(App.java:11)
Caused by: java.lang.ClassNotFoundException: com.google.gson.Gsonat java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)... 1 more
嗯?怎么找不到 Gson
包,其實是需要我們手動引入才可以,早在使用 package
時就拉取了 Gson
的 .jar
包,找到后一起運行即可。
# 再次嘗試運行
$ java -cp "work-maven-test-v0.1.0.jar:/home/ljp/.m2/repository/com/google/code/gson/gson/2.12.1/gson-2.12.1.jar" com.work.App
JSON Output: {"name":"John","age":30}
Person Name: John
Person Age: 30
終于運行成功了,但是每次都需要這么做有些麻煩,有沒有便攜的方法呢?有!
# 確保在項目根目錄下執行下面的指令
$ mvn exec:java -Dexec.mainClass="com.work.App"
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.work:work-maven-test >----------------------
[INFO] Building work-maven-test v0.1.0
[INFO] from pom.xml
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- exec:3.5.0:java (default-cli) @ work-maven-test ---
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/4.0.2/plexus-utils-4.0.2.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/4.0.2/plexus-utils-4.0.2.pom (13 kB at 5.7 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.4.0/commons-exec-1.4.0.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.4.0/commons-exec-1.4.0.pom (9.5 kB at 24 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7.1/asm-9.7.1.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7.1/asm-9.7.1.pom (2.4 kB at 3.2 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.7.1/asm-commons-9.7.1.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.7.1/asm-commons-9.7.1.pom (2.8 kB at 10 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.7.1/asm-tree-9.7.1.pom
Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.7.1/asm-tree-9.7.1.pom (2.6 kB at 9.4 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/4.0.2/plexus-utils-4.0.2.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/codehaus/plexus/plexus-utils/4.0.2/plexus-utils-4.0.2.jar (193 kB at 82 kB/s)
Downloading from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.4.0/commons-exec-1.4.0.jar
Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7.1/asm-9.7.1.jar
Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.7.1/asm-commons-9.7.1.jar
Downloading from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.7.1/asm-tree-9.7.1.jar
Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-commons/9.7.1/asm-commons-9.7.1.jar (73 kB at 98 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm-tree/9.7.1/asm-tree-9.7.1.jar (52 kB at 47 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/apache/commons/commons-exec/1.4.0/commons-exec-1.4.0.jar (66 kB at 57 kB/s)
Downloaded from central: https://repo.maven.apache.org/maven2/org/ow2/asm/asm/9.7.1/asm-9.7.1.jar (126 kB at 98 kB/s)
JSON Output: {"name":"John","age":30}
Person Name: John
Person Age: 30
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 8.002 s
[INFO] Finished at: 2025-02-11T16:21:36+08:00
[INFO] ------------------------------------------------------------------------
果然,無需我們做什么,就可以直接借用 mvn
的手來自動配置所有的依賴,可以完全確保跟著 pom.xml
填寫配置來自動管理依賴。
[!IMPORTANT]
補充:不過在有些時候不應該借助
mvn
來運行,而應該把所有的依賴都打進.jar
中,例如生產環境中是幾乎不可能安裝一個Maven
在生產環境中的,必須保證Jave
運行時環境可以直接使用.jar
包。對于我們上述的項目來說可以嘗試使用
maven-jar-plugin
插件,而對于一些spring boot
項目中,經常可以看到有人會使用spring-boot-maven-plugin
插件來把所有的依賴都打進一個.jar
包中。<project><!-- 其他的配置標簽 --><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><version>3.1.0</version><configuration><archive><manifestEntries><Main-Class>com.work.App</Main-Class></manifestEntries></archive><descriptorRefs><descriptorRef>jar-with-dependencies</descriptorRef></descriptorRefs></configuration><executions><execution><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin></plugins></build> </project>
這樣就可以直接使用
java -jar target/work-maven-test-v0.1.0-jar-with-dependencies.jar
來得到結果了。至于Spring Boot
項目的,我暫時給出下面的插件配置,但是等您了解了Spring Boot
的使用時,我們再來進行實驗。<project><!-- 其他的配置標簽 --><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> </project>
3.4.2.創建插件 Maven 項目
3.4.2.1.創建項目
接下來我們不再使用命令行的配置,而是轉為使用 IDEA
中的集成 Maven
來創建項目(因此默認使用 maven-archetype-webapp
模板來生成項目),實戰的同時編寫一個插件項目,并且通過生命階段 install
安裝到本地項目中,最好優化使用體驗,使得用戶可以在 Maven
中使用該插件來執行某一個目標。
我們定義一個額外的插件查找路徑,以 prefix:goal
方式執行自定義插件。假設您有一個 Maven
插件,名為 com.work:my-plugin
(也就是 Group ID:Artifact ID
),其中包含一個 sayhello
目標(goal
)。
并且您希望用戶能夠使用 mvn my:sayhello
,而不是完整的 mvn com.work:my-plugin:sayhello
。
[!NOTE]
吐槽:目標這個說法我懷疑是來自于
makefile
這些早期的構建工具,每一個目標說白了就是對應一個構建指令。
3.4.2.2.編寫項目
首先,您需要一個自定義 Maven
插件 my-plugin
,還是像之前一樣構建一個項目后,定義我們的 pom.xml
。
<!-- pom.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!--'xmlns=' XML 命名空間'xmlns:xsi' XML Schema 實例命名空間'xsi:schemaLocation=' 指定 XML Schema 位置這些聲明的主要作用是幫助 XML 解析器正確地驗證和處理 Maven POM 文件,確保它符合 Maven 規范。-->
<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"><!-- 指定 Maven 項目對象模型 POM 的版本 --><modelVersion>4.0.0</modelVersion><!-- 定義項目的所屬組織 --><groupId>com.work</groupId><!-- 定義項目的具體名稱 --><artifactId>my-plugin</artifactId><!-- 指定項目構建的打包類型為 .jar --><packaging>jar</packaging><!-- 定義項目的版本號 --><version>v0.1.0</version><!-- 和 artifactId 的名稱保持一樣即可(這是一個可選字段) --><name>my-plugin</name><!-- 填寫為本項目制定的官方網址 --><url>https://my-plugin.work.com</url><!-- 填寫依賴的 Java 版本 --><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><!-- 填寫所有依賴項的容器, 在內部填寫一個一個 dependency 標簽 --><dependencies><!-- 依賴名稱: 依賴官網/依賴源碼 --><!-- Junit: https://junit.org/junit5/ --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope> <!-- 如果不指定 scope 會默認將依賴設置為 compile 生命階段, 因此設置 scope 本質是確保某些依賴只在某個階段被使用 --></dependency>
、<!-- maven-plugin-api: https://maven.apache.org/ref/3.9.9/maven-plugin-api/ --><dependency><groupId>org.apache.maven</groupId><artifactId>maven-plugin-api</artifactId><version>3.8.1</version></dependency></dependencies>
</project>
[!CAUTION]
警告:編寫好
pom.xml
后一定要點擊下面這個按鈕來同步配置。
注意上面的 pom.xml
中我們引入的 maven-plugin-api
提供了用于開發 Maven
插件的核心 API
。利用依賴來實現 sayhello
目標(MyMojo.java
),是的你沒看錯 mvc
的指令是可以使用 Java
來實現的。
不過我還沒怎么仔細查閱插件開發文檔,以后有需要再補充吧,待補充…
3.5.自搭倉庫
自行搭建一個 Maven
倉庫,也還沒怎么仔細查閱文檔,以后有需要再來補充吧,待補充…