Maven

Apache

Apache 官网:https://www.apache.org/index.html#projects-list

Apache 软件基金会(Apache Software Foundation,ASF)管理和维护着众多开源项目,是全球最大的开源软件基金会,为全世界提供了大量广泛使用的软件产品。

ASF 是一个专门为支持开源软件项目而成立的非营利性组织。它的前身是 1995 年左右开始的一个开发者社区,最初的核心工作是开发和完善后来大名鼎鼎的 Apache HTTP Server,Apache HTTP Server 是整个 Apache 软件基金会的起源项目。1999 年,这个 “Apache 组织” 正式成立了基金会,为项目提供法律、财务和基础设施支持,并开创了被称为 “Apache 之道”(The Apache Way)的社区协作开发模式,其核心原则是 “社区大于代码”(Community Over Code)。

ASF 管理着超过 350 个顶级开源项目,以下是其中一些极具影响力的项目:

项目名称 主要领域 简介
Apache HTTP Server Web服务器 全球最流行的Web服务器软件,自1996年以来长期占据市场领先地位。
Apache Tomcat Java应用服务器 运行Java Servlet和JavaServer Pages(JSP)技术的开源容器,应用极为广泛。
Apache Kafka 分布式消息系统 高吞吐量的分布式事件流平台,常用于构建实时数据管道和流式应用。
Apache Hadoop 大数据处理 大数据领域的基石,提供了分布式存储(HDFS)和分布式计算(MapReduce)框架。
Apache Spark 大数据计算引擎 统一的大数据分析引擎,用于大规模数据处理,包括SQL、流处理和机器学习等。
Apache Maven 项目管理工具 软件项目管理和构建自动化工具,主要用于Java项目,管理项目构建、报告和文档。
Apache Struts Web应用框架 经典的 Java EE Web 应用程序开发框架,基于 MVC 设计模式。
Apache Ant 构建工具 基于Java的软件构建工具,通过XML文件描述构建过程,自动完成编译、测试和打包等任务。
Apache Subversion 版本控制系统 一个广泛使用的软件版本控制和修订控制系统,常被简称为“SVN”。
Apache Lucene 全文搜索引擎库 高性能、全功能的文本搜索引擎库,用Java编写,是许多搜索产品的核心。

Apache 项目已经构建了一个庞大且多元化的生态系统,覆盖了从 Web 服务器到大数据、云计算和消息系统等各个领域。

Apache Maven 是 Apache 旗下的一个开源项目,是一个项目管理和构建自动化工具,主要服务于 Java(以及 Scala、Kotlin 等 JVM 语言)项目。它通过一个项目对象模型(Project Object Model,POM)来描述项目的构建、依赖和文档,让开发者从繁琐的构建脚本中解放出来,实现 “约定优于配置”。

Maven 官网:https://maven.apache.org/

Maven 的作用

Maven 的作用主要有三个:

1️⃣ 依赖管理

2️⃣ 统一项目结构

3️⃣ 项目构建

依赖管理

方便快捷的管理项目依赖的资源(一般都是 jar 包),避免版本冲突问题。

如果没有通过 Maven 进行大型项目的依赖管理,那么在开发项目时需要引入大量的 jar 包。jar 包和 jar 包之间很多时候是需要版本匹配的,如果版本不匹配,则很容易出现版本冲突问题。

如果使用 Maven 进行项目依赖(一般都是 jar 包)管理,则可以很方便地解决这个问题,只需要在 Maven 项目的 pom.xml 文件中添加一段配置即可实现。

统一项目结构

Maven 可以提供标准、统一的项目结构。

在项目开发中,如果使用不同的开发工具(如 Eclipse、IDEA 等)创建项目工程,得到的目录结构是不同的。如果创建的是一个 Maven 工程,则自动生成统一、标准的项目目录结构。

标准的 Maven 工程目录结构:


图 1

目录说明:

  • src/main/java:Java 源代码目录
  • src/main/resources:配置文件信息
  • src/test/java:测试代码
  • src/test/resources:测试配置文件信息
  • pom.xml:项目配置文件

项目构建

Maven 提供了标准的、跨平台(Linux、Windows、MacOS)的自动化项目构建方式。


图 2

如上图所示是一个 Maven 工程,代码需要进行编译、测试、打包、发布等等操作,如果需要反复进行就显得特别麻烦,而 Maven 提供了一套简单的命令(插件)来完成项目构建。编译插件用来编译,测试插件用来测试,打包插件用来打包,等等。不同阶段会生成不同文件,比如编译阶段会生成 class 文件,打包阶段会生成 jar 包,这些生成的文件都位于 target 目录下。

Maven 核心概念

概念 说明
POM(pom.xml) Maven 的核心配置文件,定义项目坐标、依赖、插件、构建生命周期等。
坐标(GAV) groupId(组织)、artifactId(项目名)、version(版本)三者唯一标识一个构件。
仓库 本地仓库(~/.m2/repository)缓存依赖;中央仓库(中央库)和私有仓库(如 Nexus)提供构件下载。
生命周期 构建过程分为多个阶段:clean(清理)、compile(编译)、test(测试)、package(打包)、install(安装到本地)、deploy(部署到远程)。
插件 实际执行任务的是插件,比如 maven-compiler-plugin 负责编译,maven-surefire-plugin 负责测试。

Maven 常用命令

mvn clean                     # 清理 target 目录
mvn compile                   # 编译源码
mvn test                      # 运行单元测试
mvn package                   # 打包成 jar/war
mvn install                   # 将打包结果安装到本地仓库
mvn deploy                    # 部署到远程仓库(如私服)
mvn dependency:tree           # 查看依赖树,排查冲突
mvn help:effective-pom        # 查看最终生效的 POM(合并父 POM 等)

构件 artifact

在 Maven 中,构件(artifact) 是项目构建、依赖管理及发布过程中的核心实体。简单来说,artifact 就是一个由项目产生的、可被识别和复用的产物,通常表现为一个文件(如 JAR、WAR)及其关联的元数据。

1. 什么是构件?

任何一个 Maven 项目在完成编译、测试、打包等构建步骤后,最终会生成一个输出物,这个输出物就是一个 artifact。例如:

  • 一个普通的 Java 库 → my-library-1.0.0.jar
  • 一个 Web 应用 → my-webapp-1.0.0.war
  • 一个 Maven 插件 → my-plugin-1.0.0.jar(同时也是 artifact)

除了项目自身的构建结果,依赖也是 artifact。当你声明一个依赖时,Maven 会从仓库中下载对应的 artifact(如 spring-core-5.3.23.jar)并将其加入项目 classpath。

2. 构件的唯一标识:坐标(GAV)

每个 artifact 由一组坐标(coordinates)唯一确定,即:

  • groupId:组织或项目组,如 org.springframework
  • artifactId:构件名称,如 spring-core
  • version:版本号,如 5.3.23
  • packaging(可选):打包方式,如 jarwarpom,默认为 jar
  • classifier(可选):用于区分同一坐标但不同用途的构件,如 sources(源码包)、javadoc(文档包)

这组坐标(通常缩写为 GAV)在 pom.xml 中的依赖声明和项目定义中都会出现:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>5.3.23</version>
</dependency>

当 Maven 解析依赖时,它会根据坐标在仓库中定位到唯一的 artifact 文件。

3. 构件与仓库

Maven 使用仓库(repository)来存储 artifact。主要有三类仓库:

  • 本地仓库(默认 ~/.m2/repository):缓存从远程下载的 artifact 以及本地 mvn install 产生的 artifact。
  • 中央仓库:Maven 官方提供的公共仓库,包含大量开源构件。
  • 私有仓库(如 Nexus、Artifactory):组织内部自建的仓库,用于存放私有构件或代理中央仓库。

在仓库中,artifact 按坐标的层级结构存放,例如:

~/.m2/repository/org/springframework/spring-core/5.3.23/
    spring-core-5.3.23.jar
    spring-core-5.3.23.pom

每个 artifact 除了主文件(如 .jar)外,还会附带一个 .pom 文件,其中包含该构件的元数据(依赖信息、插件配置等)。Maven 正是通过读取这些 .pom 文件来解析传递性依赖的。

4. 构件的生命周期

在 Maven 构建过程中,artifact 的生成和部署与生命周期阶段紧密相关:

  • package 阶段:将项目编译结果打包成 artifact(如 JAR、WAR),并置于 target 目录。
  • install 阶段:将 artifact 安装到本地仓库,供本机其他项目使用。
  • deploy 阶段:将 artifact 上传到远程仓库(如私有仓库),供团队共享。

5. 构件与 POM 的关系

  • 每个 Maven 项目都有一个 pom.xml,该文件本身也是一个 artifact(当 packagingpom 时)。父项目的 artifact 类型通常就是 pom,它本身不包含代码,仅用于依赖管理和模块聚合。
  • 当一个 artifact 被部署到仓库时,它总是成对出现:主文件(如 JAR)和对应的 .pom 文件。.pom 文件记录了该构件的坐标、依赖、开发者信息等,是 Maven 进行依赖解析的关键依据。

6. 构件 vs 依赖

  • 构件是物理存在(文件 + 元数据)。
  • 依赖是在 pom.xml 中对某个构件的声明。

例如,你在项目中写了一个依赖:

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.13.2</version>
    <scope>test</scope>
</dependency>

Maven 会从仓库中下载 junit-4.13.2.jar(构件),并根据其作用域(test)决定是否在编译/运行时使用。

7. 理解“构件”的直观类比

可以把 Maven 的 artifact 想象成一个带有唯一身份证号的包裹

  • 身份证号 = 坐标(GAV)
  • 包裹内容 = 实际的文件(JAR、WAR 等)
  • 仓库 = 物流中心(本地是自家仓库,中央仓库是大型公共仓库,私有仓库是公司仓库)
  • 依赖声明 = 你告诉 Maven“我需要哪个包裹”,Maven 会自动去仓库取来并拆包使用

总结

概念 说明
定义 Maven 项目中可被识别、复用、发布的产物
标识 坐标(GAV + packaging + classifier)
形式 主文件(jar/war/…)+ 关联的 pom 文件
存储 本地仓库、中央仓库、私有仓库
生命周期 通过 package / install / deploy 生成并存储
与依赖关系 依赖是对构件的引用,Maven 通过坐标从仓库获取构件

理解 artifact 是掌握 Maven 依赖管理和构建机制的关键。

Maven 仓库

在 Maven 中,仓库(repository) 是统一存储和获取构件(artifact)的地方。每一个构件(如 JAR、WAR、POM 文件等)都按照其坐标(groupId、artifactId、version)组织在仓库目录中。Maven 通过仓库实现依赖的共享、重用和分发,避免了每个项目都重复存储相同的依赖包。

仓库的类型

Maven 定义了三类仓库。

本地仓库(Local Repository)

😛 位置:默认在用户目录下的 ~/.m2/repository(Windows 为 C:\Users\用户名.m2\repository)

😛 作用:缓存从远程仓库下载的构件,以及本地 mvn install 产生的构件。所有项目都共享同一个本地仓库,避免重复下载。

😛 配置:可以在 settings.xml 中通过 <localRepository> 修改路径:

<settings>
    <localRepository>/path/to/custom/repo</localRepository>
</settings>

中央仓库(Central Repository)

🤔 地址:https://repo.maven.apache.org/maven2

🤔 作用:Maven 官方维护的公共仓库,包含大量开源项目的构件。当本地仓库缺失依赖时,Maven 默认会从中央仓库下载。

🤔 特点:无需特殊配置即可使用,但国内访问速度较慢,通常会用镜像加速。

远程仓库(Remote Repository)

❇️ 定义:除了中央仓库以外的其他远程仓库,包括:

1️⃣ 私有仓库(如 Nexus、Artifactory、Apache Archiva)—— 组织内部存储私有构件或代理中央仓库。

2️⃣ 第三方镜像(如阿里云 Maven 镜像、华为云镜像)—— 加速下载。

3️⃣ 项目特定仓库——某些开源项目会发布构件到自定义仓库(如 JBoss 仓库)。

❇️ 配置:在 settings.xml(全局或用户级)或 pom.xml(项目级)中声明。

仓库的配置方式

在 settings.xml 中配置(全局/用户)

settings.xml 位于 Maven 安装目录的 conf/ 下(全局),或 ~/.m2/ 下(用户)。常用配置项:

  • 镜像(mirror):拦截对特定仓库的请求,重定向到另一个仓库。常用于替换中央仓库为国内镜像:

    <mirrors>
        <mirror>
            <id>aliyunmaven</id>
            <name>阿里云公共仓库</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <mirrorOf>central</mirrorOf>   <!-- 拦截所有对 central 的请求 -->
        </mirror>
    </mirrors>
    
  • 仓库(repository):声明额外的远程仓库(一般不推荐在 settings.xml 中直接声明,因为会影响所有项目):

    <profiles>
        <profile>
            <id>my-repos</id>
            <repositories>
                <repository>
                    <id>my-repo</id>
                    <url>https://repo.example.com/maven2</url>
                    <snapshots>
                        <enabled>true</enabled>
                    </snapshots>
                </repository>
            </repositories>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>my-repos</activeProfile>
    </activeProfiles>
    

在 pom.xml 中配置(项目级)

可以在项目 POM 中声明远程仓库,仅对当前项目生效:

<repositories>
    <repository>
        <id>jboss-public</id>
        <name>JBoss Public Repository</name>
        <url>https://repository.jboss.org/nexus/content/groups/public/</url>
        <releases><enabled>true</enabled></releases>
        <snapshots><enabled>false</enabled></snapshots>
    </repository>
</repositories>

如果需要部署构件到远程仓库,则使用 <distributionManagement>

<distributionManagement>
    <repository>
        <id>releases</id>
        <name>Releases Repository</name>
        <url>https://repo.example.com/releases</url>
    </repository>
    <snapshotRepository>
        <id>snapshots</id>
        <name>Snapshots Repository</name>
        <url>https://repo.example.com/snapshots</url>
    </snapshotRepository>
</distributionManagement>

注意:id 需与 settings.xml 中配置的服务器认证(<servers>)对应,以便 Maven 上传时进行身份验证。

仓库的查找顺序

当 Maven 需要解析一个依赖(或插件)时,按照以下顺序查找:

1️⃣ 本地仓库:如果存在直接使用,否则进入下一步。

2️⃣ 远程仓库(按配置顺序):

① 如果配置了镜像(mirror),则直接请求镜像地址。

② 否则,依次访问 pom.xml 中 <repositories> 声明的远程仓库。

③ 如果没有找到,再访问中央仓库(除非被镜像拦截)。

3️⃣ 如果所有仓库都未找到,则构建失败。

注意:插件仓库的查找顺序类似,但通过 <pluginRepositories> 配置。

先访问本地仓库,有的话就直接使用;如果本地仓库没有,则访问除了中央仓库以外的其他远程仓库,如果有的话,就下载到本地,然后访问本地的;如果除了中央仓库以外的其他远程仓库也没有,则访问中央仓库,从中央仓库下载到除了中央仓库以外的其他远程仓库,然后再从除了中央仓库以外的其他远程仓库下载到本地,最终从本地访问。如果中央仓库也没有,那么访问失败。

仓库的元数据(metadata)

每个仓库目录下除了构件文件(如 spring-core-5.3.23.jar)和对应的 POM 文件外,还会生成 maven-metadata.xml 文件。该文件记录了:

  • 构件的版本列表(用于确定最新版本)

  • 快照构件的时间戳版本(用于快照版本更新)

  • 插件信息等

例如,快照版本 1.0.0-SNAPSHOT 在仓库中实际存储为 1.0.0-20240315.083000-1.jar,通过 maven-metadata.xml 中的时间戳信息来定位最新快照。

常用命令与仓库操作

命令 作用
mvn install 将当前项目的构件安装到本地仓库
mvn deploy 将构件部署到远程仓库(需配置 distributionManagement)
mvn clean 删除项目 target 目录,不涉及仓库
mvn dependency:purge-local-repository 从本地仓库清除指定依赖(慎用)
手动删除 ~/.m2/repository 下的对应目录 强制重新下载依赖(用于解决损坏的缓存)

常见仓库配置场景

使用阿里云镜像加速

在 settings.xml 中配置:

<mirrors>
    <mirror>
        <id>aliyunmaven</id>
        <mirrorOf>central</mirrorOf>
        <name>阿里云公共仓库</name>
        <url>https://maven.aliyun.com/repository/public</url>
    </mirror>
</mirrors>

部署到私有仓库(如 Nexus)

  1. 在 settings.xml 中配置服务器认证:

    <servers>
        <server>
            <id>releases</id>
            <username>deployment</username>
            <password>deploy123</password>
        </server>
    </servers>
    
  2. 在 pom.xml 中配置 <distributionManagement>,id 与 <server> 的 id 对应。

  3. 执行 mvn deploy。

添加第三方仓库(如 Spring 里程碑仓库)

<repositories>
    <repository>
        <id>spring-milestones</id>
        <name>Spring Milestones</name>
        <url>https://repo.spring.io/milestone</url>
    </repository>
</repositories>

总结

♨️ 仓库是 Maven 的依赖缓存和分发中心,分为本地、中央、远程三种。

♨️ 本地仓库是本地缓存,中央仓库是官方公共库,远程仓库用于私有构件或加速。

♨️ 通过 settings.xml 配置镜像、认证、仓库地址,通过 pom.xml 配置项目特有的仓库和部署目标。

♨️ 仓库中的构件按坐标组织,并配合 maven-metadata.xml 管理版本。

理解仓库机制后,你可以灵活配置 Maven 的下载源、管理私有构件、加速构建过程。如果遇到依赖下载缓慢或部署失败的问题,通常可以从仓库配置入手排查。

POM

项目对象模型(Project Object Model,POM) 是 Apache Maven 的核心,是将我们自己的项目抽象成一个对象模型,该对象模型有自己专属的坐标。POM 用一个 XML 文件(pom.xml)来描述项目的配置信息、依赖关系、构建过程以及插件管理。Maven 根据这个文件来执行编译、测试、打包、部署等一系列构建生命周期任务。

项目打包会生成一个 jar,项目的依赖也都是一些 jar,因此在 POM 中项目坐标和依赖管理里面其他 jar 的坐标都是用三个标签来表示的:groupId、artifactId 和 version。

这三个标签都表示文件夹中的位置。

项目的这三个标签组成一个项目的坐标,表示这个项目打包成的 jar 包最终生成在哪个文件夹中,版本号是多少。

依赖的这三个标签组成一个依赖的坐标,指明了这个依赖(也就是一个 jar 包)在哪个文件夹中,版本号是多少。

坐标是项目和每一个依赖的唯一标识。


图 3

POM 的基本结构

一个典型的 pom.xml 包含以下关键元素:

<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>   <!-- Maven 模型版本,必须为 4.0.0 -->

    <!-- 项目坐标(GAV) -->
    <groupId>com.example</groupId>
    <artifactId>my-app</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>           <!-- 打包方式:jar、war、pom 等 -->

    <name>My Application</name>
    <description>一个示例项目</description>
    <url>http://example.com</url>

    <properties>
        <!-- 自定义属性,常用于统一版本号 -->
        <java.version>11</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <!-- 项目依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.3.23</version>
        </dependency>
    </dependencies>

    <build>
        <!-- 构建相关配置 -->
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.10.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <!-- 仓库配置(可覆盖默认中央仓库) -->
    <repositories>
        <repository>
            <id>central</id>
            <url>https://repo.maven.apache.org/maven2</url>
        </repository>
    </repositories>
</project>

POM 的核心作用

posted @ 2026-03-23 22:21  YouKong  阅读(1)  评论(0)    收藏  举报