在如今的互联网项目开发当中,特别是 Java 领域,Maven 和 Apache Commons 随处可见。

Maven 是一套强大的 Java 工程构建工具,在 GitHub 上搜索开源的 Java 项目,绝大多数都是使用 Maven 来管理的。

Apache Commons 则是一个非常有用的 Java 工具包,用于解决各种通用问题。Commons 的开发者致力于创建和维护可重用的 Java 组件,尽可能地把组件对其它库的依赖降低至最小,以便用户可以轻松的在项目中轻松地部署和使用这些组件。

如今,Apache Commons 项目已经被十分广泛地使用,光其子组件 commons-lang3 就被 GitHub 上超过 27 万个开源项目依赖。

不少人都会问,“学 Java 开发需不需要学习 Maven 和 Apache Commons?个人认为是必须要学的,这两个东西都是 JAVA 中最常用的工具、组件,可以让你的开发工作事半功倍,这和工欲善其事必先利其器是一个道理。可以说,如果你不会 Maven,有些项目你根本搞不清楚是如何运行起来的,更不用说仓库管理、依赖管理、继承和聚合等等概念了。

如果你在面试中,曾经被 Maven 和 Apache Commons “伤害” 过,那下面这门课程,可以帮助你快速学会用 Maven 构建一个标准且结构清晰的 Java 工程,并使用 Apache Commons 提供的工具类来帮助你简化开发。

课程共包含 5 个实验,适合有 Java 基础,但希望学习更多 Java 编程技巧的同学。课程将通过构建一个 Java 工程,带你熟悉 Commons Lang、Commons Collections、Commons BeanUtils、Commons Configuration 等常用组件的具体用法。


第一节、构建工具 Maven

实验介绍

Maven 在意第绪语中的意思是「知识的积累者」,最开始设计它的目的是为了简化 Jakarta Turbine 项目的构建流程。在 Jakarta Turbine 项目中,有多个子项目,每个子项目都有自己的 Ant 构建文件,但这些文件之间都只有微小的差异。

如今,Maven 已经发展成为一个可以用来构建及管理任何基于 Java 语言的项目的构建工具。

实验知识点
  • Maven 简介
  • Maven 核心概念
  • Maven 命令
  • 创建 Maven 项目
实验环境
  • Maven 3.5.4

Maven 简介

什么是构建工具?

构建工具是指一个能够自动完成和软件项目构建相关的所有操作的工具。构建一个软件项目通常包含下面的一步或多步。

  1. 生成源码。
  2. 生成源码中定义的文档。
  3. 编译源码。
  4. 将编译后的源码打包为 JAR 或 ZIP 格式文件。
  5. 将源码打包成 JAR,运行在服务器、仓库或者其他位置。

自动完成这些构建操作的好处是减少了手动操作时引发错误的风险,另外,自动构建往往比人手动操作要快捷许多。

Maven 的好处

Maven 最主要的目的是让开发人员花少量时间就能理解一个开发工作的完整状态。为了达到这个目标,Maven 在以下几个方面做出了优化和改进。

  • 简化项目构建的流程。
    虽然使用 Maven 并非完全不需要了解其底层机制,但 Maven 屏蔽了许多的细节,让我们通过简单的命令就能使用。
  • 提供一个统一的构建系统。

    Maven 通过其项目对象模型(POM)和可以被所有项目共享的插件来为项目提供统一的构建机制。你只要熟悉一个 Maven 项目的构建流程,你就了解了所有 Maven 项目的构建流程,这为你在浏览其他许多项目时节省了大量的时间。
  • 提供完备的项目信息。

    Maven 提供了大量有用的项目信息,这些信息部分来自于项目的 POM 文件,部分来自于项目的源代码。Maven 能够提供的信息如下。
  • 直接从代码管理软件中创建的更新日志。
  • 代码交叉引用。
  • 项目中管理的邮件列表。
  • 项目的依赖列表。
  • 单元测试报告以及覆盖率。

    随着 Maven 的不断改进,这些信息的展示都会继续优化,对开发者而言都会是透明的。
    同时,其他第三方产品也可以提供 Maven 插件来让他们项目的相关信息与 Maven 提供的信息一同展现出来,这也是基于 POM 的。
  • 为各种项目开发提供最佳实践的引导。

    Maven 旨在汇集所有开发的最佳实践来使新项目的引导指南更加简洁。例如,单元测试的规范、执行和报告是使用 Maven 进行标准构建的一部分,目前的单元测试最佳实践如下。
  • 将单元测试的代码与源代码分离,存放在同一级目录下。
  • 使用测试用例命名规范来定位和执行测试。
  • 让测试用例自行初始化其运行环境而不是依赖于自定义的构建。
  • Maven 还旨在协助项目工作流,例如项目的发布及问题的管理。
    最后,Maven 也对项目的目录结构制定了相关的规范,这样,开发者可以很轻松地掌握其他遵守了这一规范的项目的目录结构,省下大量的时间。
  • 让开发者可以无感知升级来适配新特性。
  • Maven 提供了一个简单的方式来让 Maven 客户端进行更新和升级,使开发者们可以不做任何改动就能享受到 Maven 的新特性。安装其他第三方插件也因此变得简单了许多。

Maven 核心概念

Maven 的核心是 POM 文件,POM 文件是一个用来表示项目资源的 XML 格式的文件,它包含了项目的源码,测试代码和项目依赖(使用到的外部 JAR)等资源的引用。

apache poi java版本 java apache commons_Apache

上图展示了 POM 文件所包含的内容,下面介绍 Maven 如何使用 POM 文件。

  1. Maven 读取 pom.xml 文件。
  2. 下载项目的依赖到本地仓库。
  3. 执行构建的生命周期中,包括构建阶段和构建目标。
  4. 执行插件。

以上操作的执行都会根据所选的构建配置文件来决定。

POM 文件

当你执行 Maven 命令时,你需要告诉 Maven 根据哪个 POM 文件来执行。Maven 会对你所指定的 POM 文件中的资源来执行相应的命令。

构建生命周期、构建阶段、构建目标

在 Maven 中,构建阶段被分为 构建生命周期、构建阶段和构建目标。一个构建生命周期由一系列构建阶段组成,而每一个构建阶段都由一系列构建目标组成。当你使用 Maven 执行一条命令时,这条命令应是一构建生命周期、构建阶段或构建目标。如果是执行一个构建生命周期,则该生命周期中所有的构建阶段都会被执行。如果是执行一个构建阶段,那么在此构建阶段被执行之前,它前面的所有阶段都会被依次执行。

依赖和仓库

Maven 最先执行的构建目标就是检查你项目的所有依赖,依赖就是项目中使用的外部 JAR 文件。如果依赖在本地仓库中没有找到,那么 Maven 就会从中央从库中进行下载,并把下载下来的依赖放到本地仓库中(当然,你可以通过配置跳过该步骤)。此外,你也可以指定 Maven 来使用哪个中央仓库进行下载(Maven 默认使用的中央仓库服务器在国外,下载速度较慢,可以换成清华或阿里的中央仓库)。

构建插件

构建插件用来向一个构建阶段添加额外的构建目标。如果你需要让 Maven 在执行构建阶段时执行一些额外的构建目标,你可以在 POM 文件中添加一个插件来达到此目的,Maven 为我们提供了一些标准插件供我们使用,你也可以使用 Java 来编写你自己的插件。

运行 Maven 需要 Java 环境的支持。

构建配置文件

构建配置文件可以让你以多种方式来构建你的项目。例如,你可能会想要在本地构建你的项目来进行开发和测试,同时你又可能需要把项目部署到远程的生产环境。这两种情况下的构建流程很可能是不同的,为了实现这个目标,你只需向你的 POM 文件中添加不同的构建配置文件,并在使用 Maven 执行构建时选择使用与环境对应的配置文件进行构建即可。

POM 文件

下面代码列出了 POM 文件中的根节点和其所有一级子节点( ... 表示省略具体的设置)。

<projectxmlns="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">
<!-- 指定 POM 版本,4.0.0 为 Maven 2 & 3 中唯一支持的版本号,且必须填写 -->
<modelVersion>4.0.0</modelVersion>
<!-- 基本设置 -->
<groupId>...</groupId>
<artifactId>...</artifactId>
<version>...</version>
<packaging>...</packaging>
<dependencies>...</dependencies>
<parent>...</parent>
<dependencyManagement>...</dependencyManagement>
<modules>...</modules>
<properties>...</properties>
<!-- 构建相关设置 -->
<build>...</build>
<reporting>...</reporting>
<!-- 与项目有关的信息设置 -->
<name>...</name>
<description>...</description>
<url>...</url>
<inceptionYear>...</inceptionYear>
<licenses>...</licenses>
<organization>...</organization>
<developers>...</developers>
<contributors>...</contributors>
<!-- 项目环境设置 -->
<issueManagement>...</issueManagement>
<ciManagement>...</ciManagement>
<mailingLists>...</mailingLists>
<scm>...</scm>
<prerequisites>...</prerequisites>
<repositories>...</repositories>
<pluginRepositories>...</pluginRepositories>
<distributionManagement>...</distributionManagement>
<profiles>...</profiles>
</project>

接下来对基本设置进行讲解,其他设置可以参考官方文档。

<projectxmlns="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>org.codehaus.mojo</groupId>
<artifactId>my-project</artifactId>
<version>1.0</version>
</project>

以上是一个 POM 文件的最小配置, groupId:artifactId:version 这三个标签是必需的。这三个标签结合起来可以实现一个地址和一个时间戳的作用,它在 Maven 仓库中定义了一个唯一的坐标,通过这个坐标,我们可以准确的找到 Maven 仓库中的任何 JAR 包。

<project>:该标签是 POM 文件的根标签,它定义了 POM 文件的命名空间,即其子标签的引用来源。

<groupId>:代表组织和整个项目的唯一标志。应遵循 Java 包命名规范。如所有 Apache 基金会的 groupId 为 org.apache

  • <artifactId>:代表该项目的全局唯一 Id,即项目的名称。
  • <version>:指定项目的版本。
  • <packaging>:定义项目以何种方式进行打包,可选值有: pomjarmaven-pluginejbwarwarearrar
  • <parent>:POM 文件是可以继承的,该标签用于指定父 POM 的相关配置。
  • <properties>:用于声明一些常量,例如上述代码中的源码编码为 UTF-8,输出代码也为 UTF-8,Java 版本为 1.8。
  • <dependencies>:依赖的根元素,里面可以包含多个 dependency 元素, dependency 里具体为各个依赖 Jar 的 3 个坐标,即 groupId、 artifactId 和 version。如果缺少 version,Maven 会尝试从父 POM 中获取该依赖的 version
  • <modules>:定义项目的子项目(子模块)。
  • <dependencyManagement>:用来管理项目子模块的依赖版本。
  • <properties>:Maven properties 是值占位符,在该标签下定义子标签,之后可以在 POM 的任何位置通过 ${} 的形式来引用其子标签的值。

Maven 目录结构

Maven 中定义了一个标准的目录结构,如果你根据该目录结构来创建你的项目,你就无需在 POM 文件中指定源码目录、测试代码目录等。Maven 的标准目录结构如下所示。

basedir
|-- pom.xml
|-- src
|   |-- main
|   |   `-- java
|   |   `-- resources
|   |   `-- filters
|   `-- test
|   |   `-- java
|   |   `-- resources
|   |   `-- filters
|   `-- it
|   `-- assembly
|   `-- site
`-- LICENSE.txt
`-- NOTICE.txt
`-- README.txt

目录

描述

src/main/java

项目源代码目录

src/main/resources

项目资源文件目录

src/main/filters

项目资源过滤文件目录

src/main/webapp

Web 应用源代码目录

src/test/java

项目测试代码目录

src/test/resources

项目测试代码资源目录

src/test/filters

项目测试代码资源过滤文件目录

src/it

集成测试代码目录(主要供插件使用)

src/assembly

组件描述符目录

src/site

站点文件目录

LICENSE.txt

项目的许可文件

NOTICE.txt

项目的注意事项文件

README.txt

项目的介绍文件

一般来说,我们无需手动创建这些目录结构。使用 Maven 自带的原型插件可以帮助我们快速创建出一个拥有目录结构的空项目。