Apache Maven是Java开发的基石,也是Java 使用最广泛的构建管理工具 。 Maven简化的基于XML的配置模型使开发人员能够快速描述或掌握任何基于Java的项目的轮廓,这使得启动和共享新项目变得很容易。 Maven还支持测试驱动的开发,长期项目维护,其声明性配置和广泛的插件使其成为CI / CD的流行选择。 本文是对Maven的快速介绍,包括Maven POM和目录结构,以及用于构建第一个Maven项目的命令。

注意,撰写本文时,最新的Maven版本是Maven 3.6.3。

Maven vs蚂蚁和Gradle

尽管Maven是最受欢迎的工具,但它并不是Java生态系统中唯一的构建工具。 Ant是较早的基于XML的配置工具,它缺乏Maven的标准化,基于约定的实践和依赖管理,但是确实提供了Maven所没有的灵活性 。 Gradle是一种较新的工具,可以在Maven生态系统之上运行(使用Maven的存储库),但是支持使用基于Groovy或Kotlin的DSL进行配置 。 这三者本身就是好的构建工具,并且每个都可以集成到CI / CD流程中 。 重要的是为您的需求选择合适的,并知道如何正确使用它。

Maven是如何工作的

像许多出色的工具一样,Maven可以将曾经过于复杂的东西(配置地狱)简化为易于消化的部分。 Maven包含三个组件:




  • POM:描述Maven项目及其依赖项的文件。
  • 目录:用于描述POM中的Maven项目的标准化格式。
  • 存储库:第三方软件的存储和发现位置。

Maven POM :每个使用Maven的Java项目在其根目录中都有一个POM(项目对象模型)文件。 pom.xml描述了项目的依赖关系,并告诉您如何构建它。 ( 依赖关系是项目所需的第三方软件。一些常见的示例是JUnit和JDBC 。有关所有可用工具和流行依赖关系的列表,请参见Maven Central存储库 。)

Maven目录 :Maven目录实现了所谓的约定优于配置 ,这是对配置地狱的一种优雅解决方案 。 Maven不需要开发人员为每个新项目定义布局和手动配置组件( makefile和Ant就是这种情况),而是建立了通用的项目结构并提供了描述其工作方式的标准文件格式。 您只需插入需求,Maven就会调用依赖项并为您配置项目。

集中存储库 :最后,Maven使用集中存储库来发现和发布项目包,并将它们作为依赖项。 当您在项目中引用依赖项时,Maven会在集中式存储库中发现它,将其下载到本地存储库,然后将其安装到您的项目中。 在大多数情况下,作为开发人员,所有这些都不可见。

访问Maven依赖项

默认情况下,Maven从Maven中央存储库解析依赖关系。 一个常见的替代方法是JCenter ,它具有更多可用的软件包。 组织还发布和托管内部存储库,这些存储库可以是公共的或私有的。 为了访问存储库,可以在Maven POM中指定其URL,或者可以指示Maven查找其他存储库

安装Maven

Maven是一个Java项目,因此在安装它之前,需要在开发环境中安装JDK。 (有关下载和安装JDK的更多信息,请参见“ 什么是JDK?Java开发工具包简介 ”。)




设置Java开发环境后,只需几个步骤即可安装Maven:

  1. 下载最新的Maven版本 (在撰写本文时为Maven 3.6.3)。
  2. apache.maven .zip文件apache.maven压缩到方便的位置。
  3. 将该文件放在您的路径上。 例如,在Unix或Linux系统上:export PATH=$PATH:/home/maven/

现在,您应该可以访问mvn命令。 键入mvn -v ,以确保您已成功安装Maven。

Maven POM

每个Maven项目的根都是pom.xml文件。 尽管XML以其乏味而著称,但在此用例中,XML实际上效果很好。 Maven的POM易于阅读,并揭示了项目中正在发生的许多事情。 (如果您使用过JavaScript,则pom.xml目的类似于Node NPM的package.json文件。)

清单1显示了一个非常简单的Maven pom.xml

清单1.简单的Maven 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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.javaworld</groupId>
  <artifactId>what-is-maven</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>Simple Maven Project</name>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>


<?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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.javaworld</groupId>
  <artifactId>what-is-maven</artifactId>
  <version>1.0-SNAPSHOT</version>
  <name>Simple Maven Project</name>
  <packaging>jar</packaging>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

了解Maven POM

一旦掌握了它,POM就不会神秘了。 首先,您可以浏览XML序言,该序言仅引用正式的POM模式。 但是请注意XML以modelVersion 。 这告诉Maven使用什么版本的POM,在本例中为Maven POM 4.0.0。

接下来,您有groupIdartifactIdversion 。 这三个属性一起唯一地标识了存储库中每个Maven管理的资源。 文件顶部的这些属性描述了您的Maven项目。

现在,看一下POM的“ dependencies部分,我们在其中描述项目的依赖项。 在这种情况下,到目前为止,我们仅引入了一种依赖关系,即JUnit。 注意,JUnit也以其groupIdartifactIdversion

无论您是描述自己的项目还是项目依赖项,这些值始终告诉Maven在Maven存储库中找到项目的位置以及可以使用的版本。

将项目托管在Maven存储库中

请记住,POM定义了项目需要运行的所有内容,但同时也将项目描述为潜在的依赖项。 如果您要构建一个将成为依赖项的项目(例如,创建供其他项目使用的库),则需要通过以下四种方式之一使它可用:

  1. 使其在本地可用。
  2. 发布到私有管理的远程存储库。
  3. 发布到基于云的私有存储库。
  4. 发布到Maven Central等公共资源库。

在第一种情况下,根本不使用远程存储库。 相反,其他开发人员将使用mvn install命令将您的项目下载并本地安装到其Maven存储库中。

在第二种情况下,您使用托管的Maven存储库,使用私有控制的服务器发布和下载依赖项。 为此,您需要一个仓库管理器,例如Apache Archiva

较新的替代方法是使用私有远程仓库,但依靠基于云的服务来管理它,例如Cloudsmith 。 这带来了远程托管的依赖项的好处,而无需建立回购服务器。 当然,这项服务是收费的。

最后,一小部分项目将最终存储在Central Maven存储库或JCenter中,这些存储库旨在用于广泛使用的公共软件包。 如果要创建供他人使用的开源依赖项,则将需要这些集中存储库之一,以使您的工作对全世界可用。

编译Maven包

如果您从清单1创建pom.xml并将其放置在目录中,则可以对其执行Maven命令。 Maven有许多命令,并且可以通过plugin使用更多命令,但是您只需要知道一些启动即可。

对于第一个命令,请尝试执行mvn package 。 即使您还没有任何源代码,执行此命令也会告诉Maven下载JUnit依赖项。 您可以检查Maven的日志记录输出以查看依赖项是否已加载。

依赖范围

您可能已经注意到示例POM中的JUnit依赖项被标记为scope test范围是依赖管理中的一个重要概念,从本质上讲,您可以定义和限制在项目中如何调用和使用每个依赖。 test范围确保运行测试时依赖项可用,但打包应用程序以进行部署时则不可用。

另一种常见的范围provided ,它告诉依赖性由运行时环境提供的框架。 部署到Servlet容器时,通常会在Servlet JARS中看到这种情况,因为该容器将提供那些JARS。 有关Maven依赖范围的完整列表,请参见Apache Maven文档。

Maven的目录结构

完成命令后,请注意Maven已创建/target目录。 这是项目输出的标准位置。 您下载的依赖项将与已编译的应用程序工件一起位于/target目录中。

接下来,您要添加一个Java文件,该文件将放置在Maven src/目录中。 创建一个/src/main/java/com/javaworld/Hello.java文件,其中包含清单2的内容。

清单2. Hello.java

com.javaworld

public class Hello {
  public static void main(String[] args){
    System.out.println("Hello, JavaWorld");
  }
}


com.javaworld

public class Hello {
  public static void main(String[] args){
    System.out.println("Hello, JavaWorld");
  }
}

/src路径是项目源文件的标准位置。 大多数项目将其主文件放在/src/main/ ,而Java文件则放在/java下的类路径中。 此外,如果要包括代码资产(例如配置文件或图像),则可以使用/src/main/resources 。 此路径中的资产将添加到主类路径。 测试文件进入/src/test/java

回顾一下,这是Maven项目结构(由Maven标准目录结构定义)的一些关键部分:

Maven标准目录结构的关键部分

pom.xml

项目描述符文件

/ src / main / java

源文件的位置

/ src / main / resources

非来源资产的位置

/ src / test / java

测试源文件的位置

/目标

构建输出的位置

管理您的Maven项目

mvn package命令指示Maven捆绑项目。 准备好将所有项目文件收集到一个位置时,发出此命令。 回想一下,在该项目的POM文件中,我们将打包类型设置为jar ,因此此命令告诉Maven将应用程序文件打包为JAR。

Maven提供了各种其他选项来控制如何管理JAR(无论是胖JAR还是瘦JAR),并指定可执行的mainclass 。 请参阅Maven文档,以了解有关Maven中文件管理的更多信息。

捆绑项目后,您可能需要发出mvn install 。 此命令将项目推送到本地Maven存储库中。 将其放入本地存储库后,即可用于本地系统中的其他Maven项目。 这对于您和/或您的团队正在创建尚未发布到中央存储库的依赖项JAR的开发场景很有用。

其他Maven命令

准备好运行在/src/java/test目录中定义的单元测试时,输入mvn test

准备编译项目的类文件时,输入mvn compile 。 如果您正在运行热部署设置,则此命令将触发热部署类加载器。 (热部署工具(如Spring Boot的mvn spring-boot:run命令)将监视类文件中的更改,并且编译将导致您的源文件被编译,正在运行的应用程序将反映这些更改。)

开始一个新项目:Maven和Spring中的原型

Maven原型是用于基于各种预定义设置启动新项目的模板。 每个原型都提供了预先打包的依赖关系,例如Java EE或Java Web应用程序项目。 您还可以从现有项目中创建新的原型,然后使用它来基于这些预定义的布局快速创建新项目。 请参阅Maven文档,以了解有关Apache Maven原型的更多信息。

与Maven配合良好的Spring框架提供了附加的,复杂的功能,可用于暂存新项目。 例如, Spring Initializr是一个工具,可让您快速定义新应用程序中所需的元素。 Initializr本身并不是Maven原型,但其目的相同,即基于前期规范生成项目布局。 在Initializr中,您可以键入mvn archetype:generate并浏览选项,以找到适合您所构建内容的原型。

添加依赖

翻译自: https://www.infoworld.com/article/3516426/what-is-maven-build-and-dependency-management-with-apache-maven.html