Java 服务器开发必备系列 —— Maven
Posted 何乐不为呢
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 服务器开发必备系列 —— Maven相关的知识,希望对你有一定的参考价值。
引言
最近开始学习 Spring Boot ,由于选用 Maven 作为构建工具,这也是 Java 后端开发常用的构建工具,当然也可以选用 Gradle
,Gradle 之前在 android 项目中使用居多,但近期也渐渐有取代 Maven 的趋势,后续可能会专门再写一篇关于 Gradle 的使用。这里先大致了解 Maven 管理项目的一些基础知识,这里主要参考官方的文档。
Maven简介
Maven
是一个项目管理和整合工具,为开发者提供了一套完整的构建生命周期框架。此工具简化和标准化了构建过程,有助于团队开发中完成如下工作:构建、文档、报告、依赖、scms、发布和分发等。
1. pom.xml
Maven 工程结构和内容通过一个 xml 文件来定义,即 pom.xml
,后续将详细说明此文件。
此外,由于 Maven 设计的理念 Conversion over configuration
,使用了约定大于配置的方式来定义构建过程,只要遵循默认的文件结构,在 pom.xml 中并不需要定义任何目录相关的配置。需要开发者定义的也只是生命周期目标和工程依赖,而且大部分工程管理和构建任务都是由 Maven 插件完成的。
2. Artifact
(工具)
又或者可以将其成为模块,可以大致理解为一个项目最终生成的文件,可以是一个 jar/war 文件、源文件或二进制文件,甚至可以是一个 pom 文件。而每个 Artifact 都是通过 groudId:artifactId:version
作为标识来唯一确定的。假如希望一个 artifact 能够在其他项目中被使用,可以将其放到本地仓库中(通过 mvn install
实现);假如希望开放一个 artifact 给所有开发者使用,也可以将其提交到 Maven 的远程仓库中。
3. Repositories
(仓库)
其实就是用来存储 artifact 的,分为本地仓库和远程仓库:
本地仓库:是指个人电脑上的指定目录,默认是系统用户目录下的
.m2/repository
目录下,也可以通过 maven 安装目录下的conf/setting.xml
中的标签来自定义;远程仓库:远程服务器上用来存储 artifact 的仓库,默认是指向 maven 的服务器仓库,也可以通过 maven 安装目录下的
conf/setting.xml
中的标签来指向其他源服务器。
项目中引用本地或远程仓库中 artifact 时,只需要在 pom.xml 中声明 dependency 即可,在编译代码时,maven 会自动根据依赖信息去下载对应的 artifact 。
4. build Lifecycles
(构建生命周期)
Maven 设了标准的项目构建生命周期,分为三类
default LifeCycle
处理项目的部署
clean LifeCycle
处理项目的清理
site LifeCycle
处理项目的文档生成
每一类生命周期,其实都包含了若干个 phase ,这里以 default LifeCycle 为例,其完整的 phase 如下:
<phases>
<phase>validate</phase>
<phase>initialize</phase>
<phase>generate-sources</phase>
<phase>process-sources</phase>
<phase>generate-resources</phase>
<phase>process-resources</phase>
<phase>compile</phase>
<phase>process-classes</phase>
<phase>generate-test-sources</phase>
<phase>process-test-sources</phase>
<phase>generate-test-resources</phase>
<phase>process-test-resources</phase>
<phase>test-compile</phase>
<phase>process-test-classes</phase>
<phase>test</phase>
<phase>prepare-package</phase>
<phase>package</phase>
<phase>pre-integration-test</phase>
<phase>integration-test</phase>
<phase>post-integration-test</phase>
<phase>verify</phase>
<phase>install</phase>
<phase>deploy</phase>
</phases>
这些 phase 都是有序的,也就是每个 phase 必须等待前面的 phase 都执行完了才会执行。
当然,我们可以执行 mvn
命令来指定执行目标 phase (也称为 goal
,每个 phase 都可以作为 goal),即只执行至某个 phase ,例如我们后面会提及的工程编译命令 mvn compile
,其实就是指定执行目标 phase 为 compile
,而在这个过程会将此 phase 之前的 validate 、initialize 、generate-sources 、process-sources 、generate-resources 和 process-resources 这里个 phase 都执行了,再执行 compile ,而此 phase 之后的 phase 则不会被执行到。
default LifeCycle 中比较重要的 phase :
alidate #验证项目是否正确以及必须的信息是否可用
compile #编译源代码
test #测试编译后的代码,即执行单元测试代码
package #打包编译后的代码,在target目录下生成package文件
integration-test #处理package以便需要时可以部署到集成测试环境
verify #检验package是否有效并且达到质量标准
install #安装package到本地仓库,方便本地其它项目使用
deploy #部署,拷贝最终的package到远程仓库和替他开发这或项目共享,在集成或发布环境完成
Maven 中的构建生命周期其实也是 Maven 最为人诟病的地方,因为把周期限制死了,无法根据实际情况添加新的 phase ,而只能将插件绑定到已有的 phase 上。
安装和配置
1. 安装配置
在 Windows 系统下安装配置 Maven 其实很简单,直接在官网下载安装包,解压缩到本地,再将其 bin
目录绝对路径配置到系统环境变量 PATH 中即可。步骤如下:
下载最新的压缩包,例如:apache-maven-3.6.0-bin.zip ;
解压然后将解压后的 bin 目录配置到系统环境变量;
在命令行输入
mvn -v
/mvn --version
测试是否安装成功,假如操作无误,则会输出如下:
Apache Maven 3.6.0 (97c98ec64a1fdfee7767ce5ffb20918da4f719f3; 2018-10-25T02:41:47+08:00)
Maven home: E:\Java\Installs\apache-maven-3.6.0\bin\..
Java version: 1.8.0_144, vendor: Oracle Corporation, runtime: D:\Android\JDK1.8\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
2. 本地仓库配置
<localRepository>E:\Java\Workplace\Maven\repo</localRepository>
3. 远程仓库配置
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
pom.xml
管理文件
项目对象模型和 POM
是 Maven 的基本工作单元, pom.xml
文件包含了 Maven 构建工程时所需的工程和配置信息,也包含了大多数工程构建的默认配置信息,是使用 Maven 来管理的项目必不可少的文件。
查看 POM 官方文档 ,而标签的各种具体使用说明,也可查看 Guide to Configuring Plug-ins
Maven 基本命令
作为一个项目管理工具,我们至少需要了解如何创建、构建和打包工程。
1. 创建工程
Maven 使用原型(archetype
)插件来创建工程,此插件实际上是从现有的 Maven 模板列表中挑选出一个作为原型,从而生成项目,接下来我们尝试生成一个 demo 工程,在命令行输入如下命令:
$ mvn archetype:generate
-DgroupId=com.linsh.test #工程包名
-DartifactId=mvn_demo #工程名称
-DarchetypeArtifactId=maven-archetype-quickstart
-DarchetypeVersion=1.4
-DinteractiveMode=false
这里几个参数的意义大致是:
DgroupId
工程的 groudId ,DartifactId
工程的 artifactId ,与后面的DarchetypeVersion
三个参数结合起来在 Maven 仓库中作为模块的唯一标示;DarchetypeArtifactId
是用于创建项目的原型模板的 artifactId ,这里我们选择的maven-archetype-quickstart
适用于创建 Java 项目,假如要创建一个 Java Web 的项目,只需选择maven-archetype-webapp
模板即可;DarchetypeVersion
是模板的版本(有时也可以忽略,默认使用最新的版本);DinteractiveMode
是否使用交互模式(由用户填写版本信息等,不使用则采用默认值)。
假如创建成功则可以看到如下输出:
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------< org.apache.maven:standalone-pom >-------------------
[INFO] Building Maven Stub Project (No POM) 1
[INFO] --------------------------------[ pom ]---------------------------------
[INFO]
[INFO] >>> maven-archetype-plugin:3.0.1:generate (default-cli) > generate-sources @ standalone-pom >>>
[INFO]
[INFO] <<< maven-archetype-plugin:3.0.1:generate (default-cli) < generate-sources @ standalone-pom <<<
[INFO]
[INFO]
[INFO] --- maven-archetype-plugin:3.0.1:generate (default-cli) @ standalone-pom ---
[INFO] Generating project in Batch mode
[INFO] ----------------------------------------------------------------------------
[INFO] Using following parameters for creating project from Archetype: maven-archetype-quickstart:1.4
[INFO] ----------------------------------------------------------------------------
[INFO] Parameter: groupId, Value: com.linsh.test
[INFO] Parameter: artifactId, Value: mvn_demo
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.linsh.test
[INFO] Parameter: packageInPathFormat, Value: com/linsh/test
[INFO] Parameter: version, Value: 1.0-SNAPSHOT
[INFO] Parameter: package, Value: com.linsh.test
[INFO] Parameter: groupId, Value: com.linsh.test
[INFO] Parameter: artifactId, Value: mvn_demo
[INFO] Project created from Archetype in dir: E:\Java\Workplace\projects\TestMaven\mvn_demo
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 11.258 s
[INFO] Finished at: 2019-01-17T10:40:05+08:00
[INFO] ------------------------------------------------------------------------
此时,在命令行当前所在目录下,会创建一个名称为 mvn_demo(与设置的 artifactId 参数值对应)的工程目录。
2. 编译工程
$ mvn compile # 或者 mvn compiler:compile
执行此命令后,工程中 src/main
目录下的 Java 源码会编程生成对应的 .class
文件到目录 target/classes
之下,假如想要编译 src/test
下的源码,可以使用如下命令:
$ mvn test-compile # 或者 mvn compiler:testCompile
编译结果放在 target/test-classes
目录下。
从 3.0 版本开始,maven 默认的编译器就是 javax.tools.JavaCompiler
,用于编译 Java 源码,假如想使用 javac
来编译,可以在编译命令中设置参数 forceJavacCompilerUse
:
$ mvn compile -Dmaven.compiler.forceJavacCompilerUse=true
除此之外,maven 目前还支持其他的编译器,例如:AspectJ
,.NET
和 C#
。
3. 清理缓存
$ mvn clean
用于清理编译和打包生成的缓存文件,其实就是把 target
目录删除掉。通常在执行打包命令之前会先调用此命令清理缓存文件,从而保证打出的包是最新的。
有时候,假如需要在每次构建工程的时候自动执行一次 clean 命令,且无需设置清理参数,可以直接在
pom.xml
中的<artifactId>maven-clean-plugin</artifactId>
标签之后添加自动清理设置,如下:<project>
[...]
<build>
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>auto-clean</id>
<phase>initialize</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
[...]
</project>如此,在工程每次构建的
initialize
阶段就会先自动执行清理命令。
4. 打包工程
$ mvn package
为了保险起见,通常在打包前先清理之前的缓存文件,所以打包命令通常如下:
$ mvn clean package
打包正常输出如下:
[INFO] Scanning for projects...
[INFO]
[INFO] ----------------------< com.linsh.test:mvn_demo >-----------------------
[INFO] Building mvn_demo 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-clean-plugin:3.1.0:clean (default-clean) @ mvn_demo ---
[INFO] Deleting E:\Java\Workplace\projects\mvn_demo\target
[INFO]
[INFO] --- maven-resources-plugin:3.0.2:resources (default-resources) @ mvn_demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\Java\Workplace\projects\mvn_demo\src\main\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:compile (default-compile) @ mvn_demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to E:\Java\Workplace\projects\mvn_demo\target\classes
[INFO]
[INFO] --- maven-resources-plugin:3.0.2:testResources (default-testResources) @ mvn_demo ---
[INFO] Using 'UTF-8' encoding to copy filtered resources.
[INFO] skip non existing resourceDirectory E:\Java\Workplace\projects\mvn_demo\src\test\resources
[INFO]
[INFO] --- maven-compiler-plugin:3.8.0:testCompile (default-testCompile) @ mvn_demo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 1 source file to E:\Java\Workplace\projects\mvn_demo\target\test-classes
[INFO]
[INFO] --- maven-surefire-plugin:2.22.1:test (default-test) @ mvn_demo ---
[INFO]
[INFO] -------------------------------------------------------
[INFO] T E S T S
[INFO] -------------------------------------------------------
[INFO] Running com.linsh.test.AppTest
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.02 s - in com.linsh.test.AppTest
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:3.0.2:jar (default-jar) @ mvn_demo ---
[INFO] Building jar: E:\Java\Workplace\projects\mvn_demo\target\mvn_demo-1.0-SNAPSHOT.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 2.052 s
[INFO] Finished at: 2019-01-19T12:39:53+08:00
[INFO] ------------------------------------------------------------------------
打包过程中完成的事情:
将
target
目录清理掉;编译工程中src 中的
main
目录下的工程源码和test
目录下的测试源码;运行测试用例,并生成对应的测试报告到
target/surefire-reports
目录下;构建工程生成 jar 文件, jar 文件的命名规则是:
(artifactId)-(version).jar
例如本工程生成的mvn_demo-1.0-SNAPSHOT.jar
,而这两项参数其实都可以在pom.xml
中进行修改。
其他
1. 常用命令
除了上述三个核心的命令之外,还有一些其他的常用命令,大致介绍如下:
mvn install
:将当前工程作为模块安装到本地的 Maven 仓库中,如此便可在其他工程中以模块的方式引入此工程;mvn site
:生成项目相关信息的文档
此外,mvn
命令除了指定 goal 外,还能添加一些参数项来排查问题,常用的参数有:
-e
显示详细错误-U
强制更新 snapshot 类型的插件或依赖库(否则maven一天只会更新一次snapshot依赖)-o
运行 offline 模式,不联网更新依赖-N
仅在当前项目模块执行命令,关闭 reactor-pl module_name
在指定模块上执行命令-ff
在递归执行命令过程中,一旦发生错误就直接退出-Dxxx=yyy
指定java全局属性-Pxxx
引用profile xxx
2. Junit
测试框架
看了 demo 工程不难发现,在 pom.xml
引入了 junit
,这其实是一个回归测试框架(只适用于 Java 工程),被开发者用于实施对应用程序的单元测试,加快程序编制速度,同时提高编码的质量。其实,查看 AppTest.java
中的源码,就会发现测试用例就是使用此框架来对应用进行单元测试的。
3. 搜索 Maven 模块
参考
Maven in 5 Minutes
Introduction to the POM
Maven Archetype
Maven Archetype Plugin/Usage
Apache Maven Compiler Plugin
Apache Maven Clean Plugin
Apache Maven Clean Plugin/Usage
Lifecycles Reference
Maven介绍,包括作用、核心概念、用法、常用命令、扩展及配置
以上是关于Java 服务器开发必备系列 —— Maven的主要内容,如果未能解决你的问题,请参考以下文章