搜索 K
Appearance
博客正在加载中...
Appearance
现在,我们从一个最简单的 HelloWorld 项目开始学习 Maven。
类似 Make 的 Makefile,Ant 的 build.xml 一样,Maven 也是通过配置文件来管理项目的,该文件就是 pom.xml。
pom 全称 Project Object Model,项目对象模型,pom.xml 里配置了项目的基本信息,如何构建,用到的依赖等等 我们新建一个 LearnJavaMaven 的文件夹,并在里面新建一个 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.peterjxl.LearnJavaMaven</groupId>
<artifactId>hello-world</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Maven Hello World Project!</name>
</project> 我们逐行说明文件的内容:
在 Maven 出现之前,一千个项目就有一千个结构,例如
而有了 Maven 后,全部项目使用统一的目录结构,这样能降低项目的学习成本。
之前我们说过,Maven 采用了约定大于配置的设计,对于项目的目录结构,也有一定的约定。常见的 Maven 项目的目录结构如下:
LearnJavaMaven
├── pom.xml
└── src
├── main
│ ├── java --存放项目的.java 文件
│ ├── resources --存放项目资源文件,如 Log4j等框架的配置文件
│ └── webapp --页面资源,HTML,JS,CSS,图片等
└── test
├── java --存放所有单元测试.java 文件,如JUnit 测试类
└── resources --- 测试资源文件在 Maven 中,默认项目的主代码目录是在 src/main/java 目录下,而测试用的代码则是在 src\test\java 目录下;resources 目录则用来存放配置文件,webapp 目录则是存放前端静态资源。 后续我们使用 Maven,都是基于这个结构来使用的,请读者务必知道这个结构。
我们根据上述约定,创建好对应的文件夹。
我们在 src/main/java 目录下创建这样的目录:com\peterjxl\learnjavamaven\demo1
然后在里面创建一个 HelloWorld 类,代码如下:
package com.peterjxl.learnjavamaven.demo1;
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello Maven!");
}
} 目前文件夹结构如下:
LearnJavaMaven
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── peterjxl
│ │ └── learnjavamaven
│ │ └── demo1
│ │ └── HelloWorld.java
│ ├── resources
│ └── webapp
└── test
├── java
└── resources
然后我们就可以用 Maven 编译了。在项目根目录下输入命令 mvn clean compile,输出如下:
> mvn clean compile
[INFO] Scanning for projects...
[INFO]
[INFO] --------------< com.peterjxl.LearnJavaMaven:hello-world >---------------
[INFO] Building Maven Hello World Project! 0.0.1-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hello-world ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ hello-world ---
[WARNING] Using platform encoding (GBK actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 0 resource
[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. build is platform dependent!
[INFO] Compiling 1 source file to D:\Projects\LearnJavaMaven\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.567 s
[INFO] Finished at: 2023-04-11T08:02:20+08:00
[INFO] ------------------------------------------------------------------------ 输出内容有点多,我们不会全部讲解其内容,重点挑一两个重要的讲,其他的后面再说。
Maven 会将构建的结果,放到项目根目录下的 target 文件夹,我们可以看第 17 行,意思是说将编译后的文件放到了 target\classes 目录下。
此时,我们目前的文件夹结构如下:
LearnJavaMaven
├── pom.xml
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── peterjxl
│ │ │ └── learnjavamaven
│ │ │ └── demo1
│ │ │ └── HelloWorld.java
│ │ ├── resources
│ │ └── webapp
│ └── test
│ ├── java
│ └── resources
└── target
├── classes
│ └── com
│ └── peterjxl
│ └── learnjavamavn
│ └── demo1
│ └── HelloWorld.class
├── generated-sources
│ └── annotations
└── maven-status
└── maven-compiler-plugin
└── compile
└── default-compile
├── createdFiles.lst
└── inputFiles.lst可以看到 Maven 帮我们生成了 target 文件夹,该文件夹就用于存放我们后续编译后的结果。
里面又有 3 个文件夹,我们重点看 classes 文件夹,可以看到 Maven 将我们的类编译好了。
我们可以试着运行:
cd ./target/classes
java com.peterjxl.learnjavamaven.demo1.HelloWorld
Hello Maven!可以看到确实编译结果是正常的。至于我们用的 Maven 命令 mvn clean compile,我们后续再讲,目前关键是运行起来项目。
在 Java 世界中, JUnit 是事实上的单元测试标准。 要使用 JUnit,首先需要为项目添加一个 JUnit 依赖, 修改项目的 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.peterjxl.LearnJavaMaven</groupId>
<artifactId>hello-world</artifactId>
<version>0.0.1-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>我们添加了第 11 至 18 行,<dependencies> 顾名思义就是很多依赖的意思,该标签体里可以放一个个 <dependency> 的标签,每个标签对应一个具体的依赖,可以是 Junit,也可以是 JDBC。
这里我们添加了 Junit 的依赖,关于 <dependency> 标签体里的内容,我们后续会讲解,目前知道这么回事就行。 配置了测试依赖,就可以编写测试类,以之前的 HelloWorld 类为例,测试 main 方法。在 src/test/java 目录下创建对应的包和测试类 HelloWorldTest.java,代码内容:
package com.peterjxl.learnjavamaven.demo1;
import org.junit.Test;
public class HelloWorldTest {
@Test
public void testMain() {
HelloWorld.main(new String[10]);
}
}测试用例编写完毕之后就可以调用 Maven 执行测试。 运行 mvn clean test:观察最后的输出如下:
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running com.peterjxl.learnjavamavn.demo1.HelloWorldTest
Hello Maven!
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.055 sec
Results :
Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 4.330 s
[INFO] Finished at: 2023-04-11T20:57:27+08:00
[INFO] ------------------------------------------------------------------------可以看到测试结果为:1 个测试用例被执行了,失败 0 个,错误 0 个,跳过 0 个(第 10 行)
将项目进行编译、 测试之后,下一个重要步骤就是打包(package) 。pom.xml 文件中没有指定打包类型, 默认打包类型 jar。 简单地执行命令 mvn clean package 进行打包,并观察最后的输出:
[INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ hello-world ---
[INFO] Building jar: D:\Projects\LearnJavaMaven\target\hello-world-0.0.1-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.728 s
[INFO] Finished at: 2023-04-11T21:06:00+08:00
[INFO] ------------------------------------------------------------------------Maven 会在打包之前执行编译、 测试等操作,并在最后告诉我们打包结果。
可以看到第 4 行告诉我们打包成功了,第 2 行告诉我们包的路径在 target 目录下。
默认打包生成的 jar 是不能够直接运行的, 因为带有 main 方法的类信息不会添加到 manifest 中。打开 jar 文件中的 META-INF/MANIFEST.MF 文件, 将无法看到 Main-Class 一行。
为了生成可执行的 jar 文件, 需要借助一个插件 maven-shade-plugin(什么是插件后续会讲), 我们配置 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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.peterjxl.LearnJavaMaven</groupId>
<artifactId>hello-world</artifactId>
<version>0.0.1-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>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation = "org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.peterjxl.learnjavamaven.demo1.HelloWorld</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>主要添加了第 20 行到 43 行,该配置是构建(build)时的配置,并配置了主类是什么(第 35 行) 然后我们再次执行 mvn clean package,并测试能否执行 main 方法:
cd target
java -jar hello-world-0.0.1-SNAPSHOT.jar
Hello Maven!运行成功。后续我们开发 JavaWeb 项目的时候,可以配置打包为 war 类型
本文我们简单讲解了 Maven 的目录结构,这里也放张图,可能更直观一点:
还介绍了 pom.xml 和一些简单的 Maven 命令。本文已将所有代码上传到 Gitee 和 GitHub 上,本文中涉及到的代码在分支 demo1HelloWorld。