第3章 maven使用入门
3.1 编写pom
Maven项目的核心是 pom.xml。POM(Project Object Model,项目对象模型)定义了项目的基本信息,用于描述项目如何构建,声明
项目依赖,等等。
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.weidaodao.mvnbook</groupId>
<artifactId>hello-world</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Wei Dao Dao Test Project</name>
</project>
代码的第一行是xml头,指定了该xml文档的版本和编码方式。紧接着是 project 元素,project 是所有 pom.xml的根元素,它还声明
了一些POM相关的命名空间及 xsd 元素,虽然这些属性不是必须的。
根元素下的第一个子元素是 modelVersion 指定了当前POM模型的版本,对于Maven2和Maven3来说,它只能是4.0.0。
这段代码中,最重要的是包含 groupId、artifactId和version三行,这3个元素定义了一个项目的基本坐标。在Maven的世界里,任何
jar、pom、或者war都是以基于这些基本的坐标进行区分的。
groupId 定义了项目属于哪个组,这个组往往和项目所在的组织或者公司关联。
artifactId 定义了当前Maven项目在组中的唯一的ID,我们为这个Hello World项目定义artifactId为hello-world。
前面groupId为 com.weidaodao.mvnbook的例子中,你可能会为不同的子项目(模块)分配artifactID,如my-app-util、
my-app-domain、myapp-web等。
顾名思义,version指定了Hello World项目的当前版本 --- 1.0-SNAPSHOT。
最后一个name元素声明了一个对于用户更为友好的项目名称。
3.2 编写主代码
项目的主代码和测试代码不同,项目的主代码会被打包到最终的构建中(如jar),而测试代码只在测试时用到,不会被打包。默认情况下,
Maven假设项目主代码位于 src/main/java 目录。我们按照Maven的约定,创建该目录
src/main/java/com/weidaodao/helloworld/HelloWorld.java。内如如下:
package com.weidaodao.mvnbook.helloworld;
public class HelloWorld {
public String sayHello() {
return "Hello Maven";
}
public static void main(String[] args) {
System.out.print(new HelloWorld().sayHello());
}
}
关于该Java代码有2点需要注意。首先,在绝大多数情况下,应该把项目主代码放到 src/main/java目录下(遵循Maven的约定),而无需额外
的配置,Maven会自动搜寻该目录找到项目主代码。其次,该Java类的包名是 com.weidaodao.mvnbook.helloworld,这与之前POM声明的
groupId和artifactId相吻合。
编写代码后,在项目根目录下运行命令 mvn clean compile。
clean 会告诉 Maven 清理输出目录 target/,compile 告诉Maven编译项目主代码,从输出中可以看到Maven首先执行了
clean:clean任务,删除 target/ 目录。默认情况下,Maven构建的所有输出都在 target/目录中;接着执行 resources:resources任务;
最后执行 compiler:compile 任务,将项目主代码编译至 target/classes目录。
上文提到的 clean:clean、resources:resources和compiler:compile对应了一些 Maven插件以及插件目标,比如clean:clean是
clean插件的clean目标,compiler:compile是 compiler插件的compile目标。
3.3 编写测试代码
Maven项目中默认的测试代码目录是 src/test/java。因此,在编写测试用例之前,应当先创建该目录。
在Java世界中,JUnit是事实上的单元测试标准。要使用JUnit,首先需要为Hello World 项目添加一个JUnit依赖,修改项目的POM如下:
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.weidaodao.mvnbook</groupId>
<artifactId>hello-world</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Wei Dao Dao Test Project</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
代码中添加了 dependencies 元素,该元素下面包含多个 dependency元素以及声明项目的依赖。这里添加了一个依赖---groupId是
junit,artifactId是junit,version是4.7。前面提到,groupId、、artifactId和version事任何一个Maven项目最基本的坐标。有了
这段声明,Maven就能够自动下载junit-4.7.jar。有了Maven,它会自动访问中央仓库(http://repo1.maven.org/maven2),下载需要的
文件。
上述POM代码中还有一个值为 test的元素scope,scope 为依赖范围。若依赖范围为test则表示该依赖只对测试有效。换句话说,测试代码
中的import JUnit代码是没有问题的,但是如果在主代码中用 import JUnit代码,就会造成编译错误。如果不声明依赖范围,那么默认值是
compile,表示该依赖对主代码和测试代码都有效。
编写测试类:src/test/java/com/weidaodao/mvnbook/helloworld/HelloWorldTest.java
package com.weidaodao.mvnbook.helloworld;
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);
}
}
一个典型的单元测试包含三个步骤:1.准备测试类及数据;2.执行要测试的行为;3.检查结果。
运行 mvn clean test;
测试代码通过编译后在 target/test-classes 下生成二进制文件,紧接着 surefire:test 任务运行测试,surefire 是Maven
中负责执行测试的插件,这里它运行测试用例 HelloWorldTest,并且输出测试报告,显示一共运行了多少测试,失败了多少,出错了多少,
跳过了多少。
3.4 打包和运行
将项目进行编译、测试之后,下一个重要的步骤就是打包(package)。Hello World的POM中没有指定打包类型,使用默认打包类型jar。
简单的执行命令 mvn clean package 进行打包,可以看到如下输出。
类似的,Maven会在打包之前执行编译、测试等操作。这里看到jar:jar任务负责打包,实际上就是jar插件目标将项目主代码打包成一个
名为 hello-world-1.0-SNAPSHOT.jar的文件。该文件也位于 target/输出目录中,它是根据 artifact-version.jar 的规则进行
命名的,如果有需要,还可以使用 finalName 来自定义该文件的名称。
至此,我们得到了项目的输出,如果有需要的话,就可以复制这个jar文件到其他项目的Classpath中从而使用 HelloWorld 类。但是,
如何才能让其他的Maven项目直接引用这个jar呢。还需要一个安装的步骤,执行 mvn clean install。
打包之后,又执行了安装任务 install:install。从输出可以看到该任务将项目输出的jar安装到了Maven本地仓库中,可以打开相应的
文件夹看到 Hello World项目的pom和jar。之前讲述的JUnit的POM及jar的下载的时候,我们说只有构建被下载到本地仓库后,才能由所有
Maven项目使用,这里是同样的道理,只有将Hello World的构建安装到本地仓库之后,其他Maven项目才能使用。
我们已经体验了 Maven 最主要的命令:
mvn clean compile
mvn clean test
mvn clean package
mvn clean install
执行test之前是会执行compile的,执行package之前是会先执行test的,install执行是会执行package。
截止目前为止,还没有运行 Hello World 项目,不要忘了 Hello World 可是有一个main方法的。默认打包生成的jar是不能直接运行的,
因为带有main方法的类信息不会添加到 manifest 中(打开jar文件中的 META-INF/MANIFEST.MF 文件,将无法看到 Main-Class 一行)。
为了生成可执行的jar文件,需要借助 maven-shade-plugin,配置该插件如下:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.juvenxu.mvnbook.helloworld.HelloWorld</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
plugin元素在POM中的相对位置在 <project><build><plugins>下面。我们配置 mainClass 为
com.weidaodao.mvnbook.helloworld.HelloWorld。现在执行 mvn clean install,待构建完成之后打开 target/目录,可以看到
hello-world-1.0-SNAPSHOT.jar和original-hello-world-1.0SNAPSHOT.jar,前者是带有Main-Class信息的可运行jar,后者是
原始的jar。
现在,在项目根目录中执行该jar文件:
java -jar hello-world-1.0-SNAPSHOT.jar
3.5 使用archetype生成项目骨架
我们称这些基本的目录结构和pom.xml文件内容称为项目的骨架。Maven提供了 Archetype 帮助我们快速勾勒出项目骨架。
mvn archetype:generate
我们实际上是在运行插件 maven-archetype-plugin,注意冒号的分割,其格式为 groupId:artifactId:version:goal。
3.6 m2eclipse简单使用
3.6.1 导入maven项目
3.6.2 创建maven项目
3.6.3 运行mvn命令
3.7 netbeans maven插件简单使用
3.7.1 打开maven项目
3.7.2 创建maven项目
3.7.3 运行mvn命令
3.Maven实战 --- maven使用入门
于 2022-06-25 23:51:49 首次发布