1

前言

本人从事JAVA编程已经有一些年月了(咳咳咳咳咳~喝一口茶),基本上在每次的项目开发过程中都会使用一些集成工具,比如说Maven或是Gradle。最近在写一个项目,但是项目在打包的过程中出现了问题,对把MAVEN一直当作傻瓜工具来使用的我完全不知道如何去解决这些问题。所以现在我想重新来了解一下这个工具,并用一种通俗易懂的方式来解释这个工具的用意。

适用人群

本教程适用于以下两种人:

  1. 初次使用MAVEN但是并没有心情阅读官网上长篇教程的童鞋
  2. 已经使用过MAVEN但对其具体工作方式根本不了解的童鞋(如我)
  3. 资深MAVEN玩家

这里欢迎所有人对文中的问题提出质疑,大家的意见笔者将非常珍惜!

在开始之前

安装MAVEN

MAVEN是用来作甚的?

官网上给出了六个单词作为MAVEN的用途,分别是

  • Builds 构建
  • Documentation 文档化
  • Reporting 报告
  • Dependencies 依赖管理
  • SCMs 配置管理
  • Releases 发布管理
  • Distribution 分布

这几个词乍一看来什么都没表述。那么我就用一些具体的例子来说明。

对于初次接触JAVA的同学来说,在Eclipse中写一个类,其中包含一个main方法,然后点击一下运行键,就可以将代码运行起来。
但是,真实世界中的项目往往十分复杂,首先,一个项目会有一个开发过程的生命周期,其中和程序员紧密相关联的步骤包括:开发,测试,集成,打包,部署。而在这些过程中,往往需要众多的程序员齐心协力完成,一个步骤可能有多个程序员并行的进行实现。更麻烦的是,在迭代开发过程中,往往会产生多个版本的产品,这些版本之间既具有共同性,又具有差异性。如何才能将各个版本进行有效的管理呢?不仅如此,在各个不同的开发时期,往往伴随着人员的调动,一个新入组的程序员如何才能更快的对项目进行了解从而投入工作呢?

这就引来了一个问题,如何才能保证每个程序员的工作成果对彼此可见,从而使每个人之间的合作更加流畅,而不是产生冲突和冗余

MAVEN就此而生。它更像是达成的某种共识。大家按照这种共识进行程序的开发。MAVEN定义了一系列开发规范,比如包的命名和功能,项目的命名等等。MAVEN中还实现了许多功能,比如自动构建,自动对依赖进行管理,自动生成项目文档等。在MAVEN的帮助下,开发人员可以尽可能的专注于代码的编写,而不是去写冗长的项目说明文档,或是进行重复的项目构建和复杂的配置管理。

别废话,先创一个MAVEN项目再说!

MAVEN本质上是一个终端工具,但是很多IDE(集成开发环境)都配有MAVEN插件,因此很多人在初次接触MAVEN使都会使用图形工具操作它。这样并不有利于学习MAVEN。建议大家以后尽量使用命令行来操控MAVEN,在熟练以后再使用图形化工具。

先打开终端(CMD或TERMINAL)进入项目目录后输出以下指令:

   mvn -B archetype:generate \
  -DarchetypeGroupId=org.apache.maven.archetypes \
  -DgroupId=com.mycompany.app \
  -DartifactId=my-app

这个指令声明了项目的名称(artifactId),项目所属的组织(groupId),以及项目初始化时使用的maven模板。

第一次使用MAVEN创建项目会比较慢,因为它会初始化一些内容。

clipboard.png

执行完毕后会产生如下如所示的目录结构,其中根目录名称为artifactId的值(在这里是my-app)。
clipboard.png
具体情况如下:
clipboard.png

在这里我们简单介绍一下根目录下各个组件的用途。
注:${basedir}是指项目的根目录,比如在我的电脑上就是/users/rale/my-app

${basedir}/src/main/java:这个目录下放置了项目的源代码,其中按照初始化时groupId的属性建好了包,每一级域名对应一个文件夹。这是MAVEN默认的建包规范。
${basedir}/src/main/java:这个目录下放置了项目的测试代码,并且在项目打包的时候不会被装入包中。这个目录底下的文件夹格式和main底下的文件夹格式相同。
pom.xml:这个文件可以说是MAVEN的核心文件,在下面详细说明。

初始化后的pom文件内容如下。

<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.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

在pom中包含了当前项目管理的全部信息。pom文件采用XML的格式存储项目的配置信息(对于XML文件不熟悉的童鞋可以自行百度,这篇文章就不详细描述其语法了)。先简单介绍一下上图这个简单的pom文件中的内容:

project: XML文件中的顶层元素
modelVersion: POM采用的模型的版本,这个元素很少改动
groupId: 开发这个项目的组织的唯一的标识号,一般采用域名的倒序
artifactId: 这个项目产品的名称
packaging : 打包的格式
version : 打包出来的版本
name: 项目的展示名称,通常用于MAVEN生成的文档中
url: 项目的网址,通常用于MAVEN生成的文档中
description: 项目的基本描述,通常用于MAVEN生成的文档中

此时maven生成的App.java文件中有一个自动实现好的hello world实例,我们可以直接编译项目并运行。
在项目的根目录下执行mvn test,maven会自动生成对应的.class文件位于${basedir}/target/classes目录下并且执行测试。可以看到下图的输出结果中说明一共一个测试用例,并且没有失败的测试用例。

clipboard.png

之后使用指令mvn package打包,打包生成的文件默认路径为${basedir}/target

clipboard.png

至此我们已经完成了MAVEN的最基本操作。

MAVEN的其他骚操作

Plugin

这里给出了添加MAVEN编译器插件的例子。

<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.3</version>
      <configuration>
        <source>1.5</source>
        <target>1.5</target>
      </configuration>
    </plugin>
  </plugins>
</build>

Maven中的插件可以附着在编译过程的不同的声明周期。一共可以分为两种类型的插件,一种是用于编译的插件,一种是用于生成报告的插件。编译的插件应当声明于<build>模块,而报告的插件应当声明于<reporting/>模块

所有的插件需要至少三个信息,groupId, artifactId和version
对于每个插件再在自己的configuration标签下详细定义。
关于plugin更多内容请参考这个网址

Dependency

这里给出了添加Junit依赖的例子

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

添加一个Dependency至少需要声明四个属性:groupId, artifactId, version, 和scope。其中scope是指在编译的哪个阶段使用该依赖,其值可以为compile test和runtime
默认情况下,所有的依赖文件都位于${user.home}/.m2/repository目录下。Maven会将不在本地的依赖下载至这个目录,并且在项目中指向这个依赖。

Plugin VS Dependency

这里可能会对Plugin和Dependency这两个概念之间产生一些困惑,似乎二者都是通过引用外部的工具完成当前项目的开发。但是这两个其实是完全不同的两个概念。
插件会绑定到指定的生命周期上,在特定的生命周期上触发。我们不会使用插件协助我们编程。
但是依赖是指我们会使用依赖的文件帮助开发,例如鼎鼎有名的JUnit。我们会使用里面的部分功能进行再次编码开发。

如何同时编译多个项目?

首先,我们需要知道的是,pom文件是可以继承的。也就是说,我们可以有父pom文件和多个子pom文件。目录格式如下:

+- pom.xml
+- my-app
| +- pom.xml
| +- src
|   +- main
|     +- java
+- my-webapp
| +- pom.xml
| +- src
|   +- main
|     +- webapp

在父pom中应当声明如下语句,将各个模块添加进来

<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.mycompany.app</groupId>
  <artifactId>app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
 
  <modules>
    <module>my-app</module>
    <module>my-webapp</module>
  </modules>
</project>

因为my-webapp需要my-app的依赖,因此在my-webapp/pom.xml文件中添加如下语句

  <dependencies>
    <dependency>
      <groupId>com.mycompany.app</groupId>
      <artifactId>my-app</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
    ...
  </dependencies>

最后在my-webapp/pom.xml和my-app中都添加如下语句继承父pom文件

  <parent>
    <groupId>com.mycompany.app</groupId>
    <artifactId>app</artifactId>
    <version>1.0-SNAPSHOT</version>
  </parent>

最后在项目的总根目录执行mvn verify可以看到项目开始一起编译

MAVEN指令汇总

mvn archetype:create -DgroupId=packageName -DartifactId=projectName:创建一个普通的MAVEN项目
mvn archetype:create -DgroupId=packageName -DartifactId=webappName -DarchetypeArtifactId=maven-archetype-webapp : 创建一个MAVEN的web应用
mvn compile:编译源代码
mvn test : 执行测试
mvn test-compile: 编译源代码和测试代码
mvn package: 将项目打包成packaging标签下声明的格式,在这里是JAR格式。默认情况下,生成的JAR包位于${basedir}/target目录下。
mvn compile:
mvn clean: 清除之前的编译结果,直观的来看就是删除${basedir}/target文件夹
mvn site: 自动生成项目简介的网站
mvn verify:运行任何检查,验证包是否有效且达到质量标准
本文还将持续更新~~~

clipboard.png
想要了解更多开发技术,面试教程以及互联网公司内推,欢迎关注我的微信公众号!将会不定期的发放福利哦~


raledong
2.7k 声望2k 粉丝

心怀远方,负重前行