Maven入門詳解

Maven入門項目

編寫POM

Maven的核心文件是pom.xml文件。POM(Project Object Model,項目對象模型)定義了項目的基本信息,用於描述如何構建、聲明項目依賴等。
簡答的測試項目如下:

在本地的一個路徑下創建一個名爲hello-world的文件夾,在該文件夾下創建一個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/maven-v4_0_0.xsd ">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.test.maven</groupId>
	<artifactId>hello-world</artifactId>
	<version>1.0-SNAPSHOT</version>
	<name>Maven Hello World Project</name>
</project>

簡單說明:

  • 第一行,xml的文件頭,固定格式,包括xml的版本和編碼方式
  • 第二行,project元素,是pom的根元素,聲明瞭一些POM相關的命名空間及xsd元素
  • 子元素modelVersion,指定了當前POM模型的版本,對於Maven2和Maven3,它只能是4.0.0
  • groupId:定義了項目屬於哪個組
  • artifactId:定義了當前項目在組中的唯一的ID
  • version:定義了當前項目的版本號。SNAPSHOT意爲快照,說明該項目還是處於開發,不穩定的版本。
  • name:聲明瞭當前項目的更爲友好的名字

添加主代碼

默認情況下,Maven假設項目主代碼位於src/main/java目錄下,遵循Maven約定,創建該目錄,然後在該目錄下創建文件com/test/maven/HelloWorld.java文件(這裏將會創建多層的文件夾,來表示 包結構)
內容如下:

package com.test.maven;

public class HelloWorld{
	public String sayHello(){
		return "Hello Maven";
	}
	
	public static void main(String[] args){
		System.out.println(new HelloWorld().sayHello());
	}
}

將java代碼放在src/main/java目錄下,無需額外的配置,Maven會自動搜索該目錄找到項目的主代碼。
編寫結束後,使用Maven編譯

mvn clean compile

clean 告訴Maven清理輸出目錄target/。
compile 告訴Maven編譯項目主目錄。
默認情況下,Maven構建的所有輸出都在target/目錄中。

E:\Test\hello-world>mvn clean compile
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Hello World Project 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hello-world ---
[INFO] Deleting E:\Test\hello-world\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-worl
d ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e
. build is platform dependent!
[INFO] skip non existing resourceDirectory E:\Test\hello-world\src\main\resource
s
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world ---

[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. buil
d is platform dependent!
[INFO] Compiling 1 source file to E:\Test\hello-world\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.156 s

從上面的信息中,可以看到**Maven執行了相關插件及插件目標**:clean:clean、resources:resources、compiler:compile。

編寫測試代碼

Maven項目中默認的測試代碼目錄是:src/test/java。在編寫測試代碼前,先創建該目錄。
修改POM文件,添加JUnit依賴。

<?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/maven-v4_0_0.xsd ">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.test.maven</groupId>
	<artifactId>hello-world</artifactId>
	<version>1.0-SNAPSHOT</version>
	<name>Maven Hello World Project</name>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

代碼中添加了dependencies元素,該元素下可以包含多個dependency元素,用來聲明項目所有的依賴。
注意
元素scope,爲依賴範圍,若依賴範圍爲test,則表示該依賴只對測試有效。
詳解:測試代碼中的import Junit的代碼是有效的,但是主代碼中用import JUnit代碼,會造成編譯錯誤。

如果不聲明依賴範圍,默認爲compile,表示該依賴對主代碼和測試代碼都有效。

在src/test/java目錄下,創建 com/test/maven/HelloWorldTest.java文件:

package com.test.maven;

import static org.junit.Assert.assertEquals;
import org.junit.Test;

public class HelloWorldTest{
	@Test
	public void testSayHello(){
		HelloWorld helloWorld = new HelloWorld();
		String result = helloWorld.sayHello();
		assertEquals("Hello Maven", result);
	}
}

用Maven執行測試,

mvn clean test
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Hello World Project 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hello-world ---
[INFO] Deleting E:\Test\hello-world\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-worl
d ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e
. build is platform dependent!
[INFO] skip non existing resourceDirectory E:\Test\hello-world\src\main\resource
s
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world ---

[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. buil
d is platform dependent!
[INFO] Compiling 1 source file to E:\Test\hello-world\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ he
llo-world ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e
. build is platform dependent!
[INFO] skip non existing resourceDirectory E:\Test\hello-world\src\test\resource
s
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ hello-w
orld ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. buil
d is platform dependent!
[INFO] Compiling 1 source file to E:\Test\hello-world\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello-world ---
[INFO] Surefire report directory: E:\Test\hello-world\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.test.maven.HelloWorldTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.078 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.864 s

執行細節中,看到compiler:testCompile 任務執行成功了,測試代碼通過編譯後在target\test-classes下生成了二進制文件,緊接着surefire:test 任務運行測試(surefire是Maven中負責執行測試的插件)。

打包

Maven命令

mvn clean package

執行結果:

[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building Maven Hello World Project 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hello-world ---
[INFO] Deleting E:\Test\hello-world\target
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-worl
d ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e
. build is platform dependent!
[INFO] skip non existing resourceDirectory E:\Test\hello-world\src\main\resource
s
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ hello-world ---

[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. buil
d is platform dependent!
[INFO] Compiling 1 source file to E:\Test\hello-world\target\classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ he
llo-world ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e
. build is platform dependent!
[INFO] skip non existing resourceDirectory E:\Test\hello-world\src\test\resource
s
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ hello-w
orld ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding GBK, i.e. buil
d is platform dependent!
[INFO] Compiling 1 source file to E:\Test\hello-world\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ hello-world ---
[INFO] Surefire report directory: E:\Test\hello-world\target\surefire-reports

-------------------------------------------------------
 T E S T S
-------------------------------------------------------
Running com.test.maven.HelloWorldTest
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.07 sec

Results :

Tests run: 1, Failures: 0, Errors: 0, Skipped: 0

[INFO]
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello-world ---
[INFO] Building jar: E:\Test\hello-world\target\hello-world-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.002 s

可以看到 jar:jar 任務負責打包。(jar插件的jar目標)

安裝

Maven命令

mvn clean install

執行結果:

[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello-world ---
[INFO] Building jar: E:\Test\hello-world\target\hello-world-1.0-SNAPSHOT.jar
[INFO]
[INFO] --- maven-install-plugin:2.4:install (default-install) @ hello-world ---
[INFO] Installing E:\Test\hello-world\target\hello-world-1.0-SNAPSHOT.jar to C:\
Users\Administrator\.m2\repository\com\test\maven\hello-world\1.0-SNAPSHOT\hello
-world-1.0-SNAPSHOT.jar
[INFO] Installing E:\Test\hello-world\pom.xml to C:\Users\Administrator\.m2\repo
sitory\com\test\maven\hello-world\1.0-SNAPSHOT\hello-world-1.0-SNAPSHOT.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.620 s

可以看到,Maven執行了安裝任務 install:install。Maven已經把jar包安裝到Maven本地倉庫中了。

運行

默認打包生成的jar是不能夠直接運行的,因爲main方法的類信息不會添加到mainfest中(打開jar文件中的META-INF/MAINFEST.MF文件,將無法看到Main-Class這一行)。

將藉助 maven-shade-plugin生成可執行jar文件,添加插件內容,新的完整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/maven-v4_0_0.xsd ">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.test.maven</groupId>
	<artifactId>hello-world</artifactId>
	<version>1.0-SNAPSHOT</version>
	<name>Maven Hello World Project</name>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-shade-plugin</artifactId>
			<version>1.4</version>
			<executions>
				<execution>
					<phase>package</phase>
					<goals>
						<goal>shade</goal>
					</goals>
					<configuration>
						<transformers>
							<!-- 打成可執行的jar包 的主方法入口-->
							<transformer
								implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
								<mainClass>com.test.maven.HelloWorld</mainClass>
							</transformer>
						</transformers>
					</configuration>
				</execution>
			</executions>
		</plugin>
	</plugins>
	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.7</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
</project>

保存上面的POM文件後,再次執行:

mvn clean package

打開新的jar文件,就可以看到META-INF\MANIFEST.MF文件中多了下面一行

Main-Class: com.test.maven.HelloWorld

在根目錄下,打開cmd,執行該jar文件,語句如下

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

控制檯輸出:Hello Maven

使用Archetype來生成項目骨架

通過上面入門項目的步驟,主要體會Maven默認約定的思想。但是實際開發中,這種效率還是比較麻煩的。
可以通過Maven的插件Archetype來構建項目的骨架。
命令如下:

mvn archetype:generate

選定目錄,執行後,Maven將會去下載maven-archetype-plugin插件。
然後根據提示,輸入相關信息即可。

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