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插件。
然后根据提示,输入相关信息即可。

猜你喜欢

转载自blog.csdn.net/weixin_44728363/article/details/89067390
今日推荐