Maven入门到进阶:构建、依赖与插件管理详解

文章目录

一、Maven介绍

1、什么是Maven

Maven是Apache软件基金会开发的一款项目管理构建工具,主要用于Java 项目的构建依赖管理项目生命周期管理。Maven通过声明性配置(XML 文件)定义项目构建流程及依赖项,使得项目管理更简单、更高效,特别适合于多模块、大型项目。

2、Maven的核心功能

  • 依赖管理:自动解析、下载和管理项目所需的外部依赖库,避免手动查找和添加 JAR 包
  • 构建管理:通过标准化的构建生命周期(例如 clean、compile、test、package、install、deploy),帮助用户自动化地编译代码、运行测试、打包成JAR/WAR包等
  • 插件扩展:Maven 拥有丰富的插件生态系统,能够扩展构建过程中的功能,包括代码质量检查、测试覆盖率报告、打包部署等
  • 项目统一管理:Maven允许通过父子项目、聚合项目等结构,统一管理多模块项目,使团队协作更高效

二、Maven核心概念

1、坐标GAVP

在Maven中,GAVP是构建项目的四个核心属性的缩写,分别代表GroupIdArtifactIdVersionPackaging。这四个属性在pom.xml文件中定义,用于唯一标识一个Maven项目或依赖。

1.1、GroupId

  • 定义:项目或组件的组ID,通常表示项目所在的组织、公司或团队

  • 用途:帮助区分不同的项目组和模块。GroupId通常以域名倒置的格式(如com.example)命名,以避免命名冲突

  • 示例

    xml 复制代码
    <groupId>com.example</groupId>

1.2、ArtifactId

  • 定义:项目或模块的标识符,是项目的名称或模块名称,通常是小写的、简短的名称

  • 用途:用于唯一标识项目中的某个模块。通常一个项目会有多个模块,每个模块的ArtifactId都是唯一的

  • 示例

    xml 复制代码
    <artifactId>my-app</artifactId>

1.3、Version

  • 定义:项目的版本号,通常遵循语义化版本号(如1.0.01.0-SNAPSHOT等)

  • 用途:帮助区分不同版本的构件。Maven支持SNAPSHOT版本(用于开发阶段)和RELEASE版本(用于发布的稳定版本)

  • 示例

    xml 复制代码
    <version>1.0.0</version>
1.3.1、版本号的组成
  • Maven的版本号通常由主版本号次版本号补丁版本号标识符组成。其基本格式如下:
xml 复制代码
<major>.<minor>.<patch>-<qualifier>
  • 主版本号 (Major Version)
    • 作用: 主版本号在项目发生重大更改,可能导致向后不兼容时会更新。例如,修改了API接口或删除了某些功能,升级主版本号
    • 示例 : 1.0.02.0.0
  • 次版本号 (Minor Version)
    • 作用: 次版本号通常表示项目有了新功能,但向后兼容。例如,增加了新功能,但不影响现有功能的使用
    • 示例 : 1.0.01.1.0
  • 补丁版本号 (Patch Version)
    • 作用: 补丁版本号通常用于修复错误或进行小的改进,确保向后兼容
    • 示例 : 1.0.01.0.1
  • 标识符 (Qualifier)
    • 作用: 标识符用于标识预发布版本或特殊版本,比如快照版本、测试版或里程碑版本
    • 常见的附加标识符有以下几种
附加标识符 含义 适用阶段 示例
SNAPSHOT 开发中的不稳定版本,尚未发布 开发过程 1.0.0-SNAPSHOT
ALPHA 早期测试版本,可能包含较多 bug,功能未完全实现 内部测试 1.0.0-ALPHA
BETA 稳定性较高的测试版本,功能基本完成 公开测试 1.0.0-BETA
RC 候选发布版本,接近正式版本 发布前测试 1.0.0-RC1
M 里程碑版本,标志关键特性的阶段性完成 项目阶段性成果 1.0.0-M1
GA 正式发布版本,供所有用户使用 正式发布 1.0.0-GA
FINAL 最终稳定版本,适合大规模使用 正式发布 1.0.0-FINAL
HOTFIX 紧急修复版本,快速解决严重问题 紧急修复 1.0.1-HOTFIX
DEV 开发版本,类似于 SNAPSHOT 开发过程 1.0.0-DEV
CUSTOM 定制版本,针对特定客户或项目需求 定制化发布 1.0.0-CUSTOM
PREVIEW 预览版本,展示即将发布的功能 用户或客户展示 1.0.0-PREVIEW
CANARY 实验版,用于有限发布和生产环境验证 实验性发布 1.0.0-CANARY
EAP Early Access Program,早期访问版 内部或有限外部访问 1.0.0-EAP
NIGHTLY 每晚构建的版本,通常用于开发中的自动化测试 开发过程 1.0.0-NIGHTLY
STAGING 预发布版本,通常用于发布到生产环境前的测试 预生产环境 1.0.0-STAGING
TEST 用于测试目的的版本,可能包含调试信息 内部测试 1.0.0-TEST
INTEGRATION 用于集成测试的版本 集成测试 1.0.0-INTEGRATION
DEMO 演示版本,通常用于客户或内部展示 展示用途 1.0.0-DEMO
EXPERIMENTAL 实验版本,包含实验性功能或不稳定的更改 开发测试 1.0.0-EXPERIMENTAL
LTS 长期支持版本,通常包含稳定且经验证的功能 正式发布 1.0.0-LTS
RELEASE 稳定的正式发布版本,类似于 GA 和 FINAL 正式发布 1.0.0-RELEASE
ROLLOUT 渐进式发布版本,逐步向用户推广 渐进式发布 1.0.0-ROLLOUT
PATCH 小型补丁版本,用于特定问题的快速修复 快速修复 1.0.1-PATCH
  • snapshot表示快照版,它不是个稳定版本,属于开发过程中使用的版本
  • 当一个项目开发完成后,就会进入测试版本,而测试版本一般会分为内部测试alpha版外部测试beta版两种
  • 当测试通过后,将会进入正式版本,大部分的正式版是啥也不带,就一个单纯的版本号,比如1.0、1.7.1等。也有个别的是这些rc、final、release、ga

1.4、Packaging

  • 定义:指定项目的打包类型,决定了Maven最终生成的文件格式

  • 常见的打包类型

    • jar:用于生成Java的jar文件
    • war:用于生成Web应用的war文件
    • pom:通常用于父项目聚合项目,表示该项目不会打包成可执行文件,而是用于组织多个模块
  • 示例

    xml 复制代码
    <packaging>jar</packaging>

2、POM、父POM和超级POM

2.1、POM (Project Object Model)

POM是Maven项目的核心文件,通常命名为pom.xml,包含了项目的配置信息、依赖关系、插件、构建设置等。每个Maven项目都需要一个POM文件,它决定了如何构建和管理项目。

以下是一个详细的 pom.xml 样例:

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/maven-v4_0_0.xsd">
    <!-- modelVersion: 定义 POM 文件的版本,通常为 4.0.0 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- groupId: 项目的组 ID,通常是项目所在组织的域名反转形式 -->
    <groupId>com.example</groupId>

    <!-- artifactId: 项目的标识符,通常是项目的名称 -->
    <artifactId>my-app</artifactId>

    <!-- version: 项目的版本号 -->
    <version>1.0.0</version>

    <!-- packaging: 打包类型,默认为 jar。其他值可以是 war、pom 等 -->
    <packaging>jar</packaging>

    <!-- name: 项目的名称(可选) -->
    <name>My Application</name>

    <!-- description: 项目的简短描述(可选) -->
    <description>This is my first Maven project.</description>

    <!-- url: 项目主页的 URL(可选) -->
    <url>http://www.example.com/my-app</url>

    <!-- licenses: 项目使用的许可证信息 -->
    <licenses>
        <license>
            <name>Apache License, Version 2.0</name>
            <url>http://www.apache.org/licenses/LICENSE-2.0</url>
            <distribution>repo</distribution>
        </license>
    </licenses>

    <!-- developers: 项目的开发人员信息 -->
    <developers>
        <developer>
            <id>johndoe</id>
            <name>John Doe</name>
            <email>johndoe@example.com</email>
            <organization>Example Org</organization>
            <roles>
                <role>developer</role>
            </roles>
        </developer>
    </developers>

    <!-- dependencies: 定义项目依赖的外部库 -->
    <dependencies>
        <dependency>
            <!-- groupId: 依赖的组 ID -->
            <groupId>org.springframework</groupId>
            <!-- artifactId: 依赖的标识符 -->
            <artifactId>spring-core</artifactId>
            <!-- version: 依赖的版本 -->
            <version>5.2.9.RELEASE</version>
            <!-- scope: 依赖的作用范围,默认为 compile,还可以是 test、provided、runtime 等 -->
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.1</version>
            <scope>test</scope> <!-- 仅在测试阶段使用 -->
        </dependency>
    </dependencies>

    <!-- build: 构建配置,如插件、资源等 -->
    <build>
        <plugins>
            <plugin>
                <!-- 编译插件 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <!-- 设置 Java 编译版本 -->
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <!-- 测试报告生成插件 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>

    <!-- properties: 项目属性,通常用来定义全局变量 -->
    <properties>
        <!-- Maven 编译器的 Java 源代码版本 -->
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <!-- repositories: 自定义 Maven 仓库 -->
    <repositories>
        <repository>
            <id>central</id>
            <name>Maven Central Repository</name>
            <url>https://repo.maven.apache.org/maven2</url>
        </repository>
    </repositories>

    <!-- profiles: 定义构建配置的不同环境 -->
    <profiles>
        <profile>
            <id>development</id>
            <properties>
                <!-- 开发环境专用属性 -->
                <maven.compiler.source>11</maven.compiler.source>
            </properties>
        </profile>

        <profile>
            <id>production</id>
            <properties>
                <!-- 生产环境专用属性 -->
                <maven.compiler.source>1.8</maven.compiler.source>
            </properties>
        </profile>
    </profiles>
</project>

2.1、父POM(Parent POM)

父POM文件位于项目的根目录,通常用于多模块项目的配置。它包含公共依赖项、插件版本、构建配置等,供子模块继承。父POM可以被称为"聚合POM"或"根POM",并且会定义<modules>标签来指定所有子模块。

以下是一个详细的父pom.xml 样例:

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/maven-v4_0_0.xsd">
    <!-- modelVersion: 定义 POM 文件的版本,通常为 4.0.0 -->
    <modelVersion>4.0.0</modelVersion>

    <!-- groupId: 定义父 POM 的组 ID -->
    <groupId>com.example</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0.0</version>

    <!-- packaging: 父 POM 一般使用 pom 作为打包类型 -->
    <packaging>pom</packaging>

    <!-- modules: 定义子模块 -->
    <modules>
        <module>module-one</module>
        <module>module-two</module>
    </modules>

    <!-- properties: 定义共享的属性,用于子项目继承 -->
    <properties>
        <!-- 定义所有模块的全局 Java 编译器版本 -->
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <!-- 项目版本定义,可供子模块继承使用 -->
        <spring.version>5.2.9.RELEASE</spring.version>
        <junit.version>4.13.1</junit.version>
    </properties>

    <!-- dependencyManagement: 用于管理子模块的依赖版本 -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>${spring.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- build: 配置构建相关信息 -->
    <build>
        <plugins>
            <plugin>
                <!-- maven-compiler-plugin 插件,用于设置编译器版本 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${maven.compiler.source}</source>
                    <target>${maven.compiler.target}</target>
                </configuration>
            </plugin>

            <plugin>
                <!-- maven-surefire-plugin 插件,用于执行单元测试 -->
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>

    <!-- profiles: 用于定义不同环境下的构建配置 -->
    <profiles>
        <profile>
            <id>development</id>
            <properties>
                <!-- 开发环境中使用 Java 11 -->
                <maven.compiler.source>11</maven.compiler.source>
                <maven.compiler.target>11</maven.compiler.target>
            </properties>
        </profile>
        <profile>
            <id>production</id>
            <properties>
                <!-- 生产环境中使用 Java 8 -->
                <maven.compiler.source>1.8</maven.compiler.source>
                <maven.compiler.target>1.8</maven.compiler.target>
            </properties>
        </profile>
    </profiles>

    <!-- repositories: 定义自定义 Maven 仓库 -->
    <repositories>
        <repository>
            <id>central</id>
            <url>https://repo.maven.apache.org/maven2</url>
        </repository>
    </repositories>
</project>

2.3、超级POM(Super POM)

超级POM是Maven提供的默认全局POM文件,所有的Maven项目都会隐式继承这个超级POM。它是Maven的顶级POM,定义了Maven项目构建的默认行为。即使项目没有显式指定任何父POM,它也会自动继承超级POM中的基本设置。

超级pom定义在maven-model-builder.jar中,如果想查看其定义,需要将jar包解压,解压后超级pom的完整路径为: maven 安装目录\lib\maven-model-builder-3.8.6.jar\org\apache\maven\model\pom-4.0.0.xml,内容如下:

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>

<project>
  <!-- 定义 POM 文件的版本,通常为 4.0.0 -->
  <modelVersion>4.0.0</modelVersion>

  <!-- repositories 元素定义 Maven 用于解析依赖的仓库 -->
  <repositories>
    <repository>
      <!-- id 是仓库的唯一标识符,代表 Maven Central 仓库 -->
      <id>central</id>
      <!-- name 是仓库的名称,描述性字段 -->
      <name>Central Repository</name>
      <!-- url 定义了仓库的网络地址 -->
      <url>https://repo.maven.apache.org/maven2</url>
      <!-- layout 定义了仓库的布局,默认为 default -->
      <layout>default</layout>
      <snapshots>
        <!-- 禁用从该仓库下载快照版本 -->
        <enabled>false</enabled>
      </snapshots>
    </repository>
  </repositories>

  <!-- pluginRepositories 元素用于定义 Maven 插件的仓库 -->
  <pluginRepositories>
    <pluginRepository>
      <!-- 插件仓库的唯一标识符,与普通仓库类似 -->
      <id>central</id>
      <!-- 仓库的名称 -->
      <name>Central Repository</name>
      <!-- 仓库的 URL 地址 -->
      <url>https://repo.maven.apache.org/maven2</url>
      <!-- 仓库的布局,默认值为 default -->
      <layout>default</layout>
      <snapshots>
        <!-- 禁用快照版本的插件下载 -->
        <enabled>false</enabled>
      </snapshots>
      <releases>
        <!-- 定义如何更新发布版本的策略,never 表示从不更新 -->
        <updatePolicy>never</updatePolicy>
      </releases>
    </pluginRepository>
  </pluginRepositories>

  <!-- build 元素定义了构建过程中的目录、插件和资源管理 -->
  <build>
    <!-- 定义编译输出的目录,通常为 target 文件夹 -->
    <directory>${project.basedir}/target</directory>
    <!-- 定义编译后的类文件的输出目录 -->
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <!-- 定义构建输出文件的最终名称,通常包括 artifactId 和版本号 -->
    <finalName>${project.artifactId}-${project.version}</finalName>
    <!-- 定义测试编译后的输出目录 -->
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <!-- Java 源代码的目录,默认为 src/main/java -->
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <!-- 脚本源文件的目录 -->
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <!-- 测试源代码的目录,默认为 src/test/java -->
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <!-- 定义项目的主资源文件目录,通常用于配置文件等 -->
    <resources>
      <resource>
        <directory>${project.basedir}/src/main/resources</directory>
      </resource>
    </resources>
    <!-- 定义测试资源文件目录 -->
    <testResources>
      <testResource>
        <directory>${project.basedir}/src/test/resources</directory>
      </testResource>
    </testResources>

    <!-- pluginManagement 元素管理所有的插件版本和配置,供子项目继承 -->
    <pluginManagement>
      <!-- NOTE: 以下插件将在未来版本的超级 POM 中移除 -->
      <plugins>
        <!-- 定义了 maven-antrun-plugin 插件及其版本 -->
        <plugin>
          <artifactId>maven-antrun-plugin</artifactId>
          <version>1.3</version>
        </plugin>
        <!-- 定义了 maven-assembly-plugin 插件及其版本,用于生成项目打包配置 -->
        <plugin>
          <artifactId>maven-assembly-plugin</artifactId>
          <version>2.2-beta-5</version>
        </plugin>
        <!-- 定义了 maven-dependency-plugin 插件及其版本,管理项目依赖 -->
        <plugin>
          <artifactId>maven-dependency-plugin</artifactId>
          <version>2.8</version>
        </plugin>
        <!-- 定义了 maven-release-plugin 插件及其版本,管理项目发布流程 -->
        <plugin>
          <artifactId>maven-release-plugin</artifactId>
          <version>2.5.3</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>

  <!-- reporting 元素用于生成项目报告的输出目录 -->
  <reporting>
    <outputDirectory>${project.build.directory}/site</outputDirectory>
  </reporting>

  <!-- 
  	profiles 元素定义了项目的构建配置文件
  	需要mvn clean install -DperformRelease=true才能生效
   -->
  <profiles>
    <!-- 定义一个 profile,名为 release-profile -->
    <profile>
      <id>release-profile</id>

      <!-- activation 元素定义激活 profile 的条件 -->
      <activation>
        <!-- 当属性 performRelease 为 true 时激活此 profile -->
        <property>
          <name>performRelease</name>
          <value>true</value>
        </property>
      </activation>

      <build>
        <plugins>
          <!-- 继承自父 POM 的 maven-source-plugin 插件 -->
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-source-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-sources</id>
                <goals>
                  <!-- 生成源码 jar 包 -->
                  <goal>jar-no-fork</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <!-- 继承自父 POM 的 maven-javadoc-plugin 插件,用于生成 Javadoc -->
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-javadoc-plugin</artifactId>
            <executions>
              <execution>
                <id>attach-javadocs</id>
                <goals>
                  <!-- 生成 Javadoc jar 包 -->
                  <goal>jar</goal>
                </goals>
              </execution>
            </executions>
          </plugin>
          <!-- 继承自父 POM 的 maven-deploy-plugin 插件 -->
          <plugin>
            <inherited>true</inherited>
            <artifactId>maven-deploy-plugin</artifactId>
            <configuration>
              <!-- 配置更新发布信息 -->
              <updateReleaseInfo>true</updateReleaseInfo>
            </configuration>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>

</project>

也正是超级pom中build元素定义了构建过程中的源码文件配置文件等资源目录,才有如下约定的目录要求。

2.4、有效POM(Effective POM)

有效POM(Effective POM)是Maven生成的最终POM文件,它将项目POM文件与父POM、超级POM以及各种继承和聚合的配置组合在一起,形成一个完整的项目配置。有效POM包含了项目中所有继承的配置、依赖、插件等信息,即项目实际构建时使用的完整POM。

2.4.1、如何查看有效POM?
xml 复制代码
mvn help:effective-pom

示例输出:

xml 复制代码
<project>
  <modelVersion>4.0.0</modelVersion>
  
  <groupId>com.example</groupId>
  <artifactId>my-project</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
  
  <build>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.22.2</version>
      </plugin>
      <plugin>
        <artifactId>maven-jar-plugin</artifactId>
        <version>3.1.0</version>
      </plugin>
      <!-- 其他插件 -->
    </plugins>
  </build>
  
  <dependencies>
    <!-- 列出所有依赖,包括直接声明的和继承来的 -->
  </dependencies>
  
  <!-- 其他配置 -->
</project>

如果使用mvn help:effective-pom命令时,输出的内容过多导致最上面的部分被截断输出到文件并打开

  • 在Linux或macOS中,执行以下命令可以将输出保存到文件后立即打开它
bash 复制代码
mvn help:effective-pom > effective-pom.xml && open effective-pom.xml
  • 在Windows上可以使用
cmd 复制代码
mvn help:effective-pom > effective-pom.xml && start effective-pom.xml
2.4.2、有效POM的用途
  • 调试配置问题:帮助你理解为什么某个依赖或插件会被使用,或者为何某个插件没有被使用
  • 查看默认插件:帮助查看所有自动添加的插件和它们的版本
  • 验证继承和聚合:确保项目继承了正确的配置,尤其是当项目使用多模块或父子POM时

三、Maven依赖管理

Maven依赖管理是Maven最强大的功能之一,它通过自动下载和管理项目所需的外部库插件,使开发者无需手动配置这些依赖项。

1、依赖范围

  • 通过设置坐标的依赖范围,可以设置对应jar包的作用范围
    • 编译环境:在源代码的目录src/main/java下可以使用
    • 测试环境:在测试源代码的目录src/test/java下可以使用
    • 运行环境:生成的war或可执行jar的lib下有对应的jar

1.1、compile(编译范围)

  • 描述:默认依赖范围。所有没有明确指定范围的依赖,都会使用compile范围

  • 作用:在编译测试运行时均可用

  • 使用场景:对于大多数核心库,如框架类库(例如 Spring),都应使用compile范围

  • 示例:

    xml 复制代码
    <dependency>
        <groupId>org.example</groupId>
        <artifactId>example-lib</artifactId>
        <version>1.0</version>
    </dependency>

1.2、provided(已提供范围)

  • 描述:运行时需要由应用服务器或容器提供该依赖

  • 作用:在编译测试时可用,但不会在运行时包含在打包文件中

  • 使用场景:适用于需要在应用服务器或其他容器(如 Tomcat)中提供的依赖。例如,Servlet API 需要由 Web 服务器提供

  • 示例:

    xml 复制代码
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>4.0.1</version>
        <scope>provided</scope>
    </dependency>
  • 如图tomcat也就是部署的服务器本身就提供了

1.3、runtime(运行时范围)

  • 描述:主要用于那些不在编译阶段使用,但需要在项目运行时加载的库

  • 作用:在运行测试时可用,但不会在编译时使用

  • 使用场景:JDBC驱动实现依赖,其在编译时只需JDK提供的JDBC接口,只有测试、运行阶段才需要实现了JDBC接口的驱动

  • 示例:

    xml 复制代码
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.25</version>
        <scope>runtime</scope>
    </dependency>

1.4、test(测试范围)

  • 描述:通常用于JUnit、TestNG等测试框架

  • 作用:只在测试环境src/test/java下可用,编译和运行时不可用

  • 使用场景:适用于所有测试相关的库,如测试框架

  • 示例:

    xml 复制代码
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.2</version>
        <scope>test</scope>
    </dependency>

1.5、system(系统范围)

  • 描述:系统范围的依赖类似于provided,但它需要手动提供JAR文件,并通过systemPath明确指明依赖的路径

  • 作用:在编译测试时可用,但不会在运行时包含。(project.basedir是maven的预定义变量,表示当前项目的根目录路径

  • 使用场景:适用于系统自带的库,或需要本地使用的特定JAR文件

  • 打包插件配置<includeSystemScope>true</includeSystemScope>,否则可执行jar中lib没有此依赖

  • 示例:

    xml 复制代码
      <dependency>
          <groupId>com.xc.maven</groupId>
          <artifactId>xc-maven-test</artifactId>
          <version>1.0-SNAPSHOT</version>
          <systemPath>${project.basedir}/src/main/resources/lib/open-api-sdk-2.0.jar</systemPath>
          <scope>system</scope>
      </dependency>
      <!--配合打包插件配置-->
      <build>
          <plugins>
              <plugin>
                  <groupId>org.springframework.boot</groupId>
                  <artifactId>spring-boot-maven-plugin</artifactId>
                  <configuration>
                      <includeSystemScope>true</includeSystemScope>
                  </configuration>
              </plugin>
          </plugins>
      </build>

1.6、import(导入范围)

  • 描述:import是一种特殊的依赖范围,通常在依赖管理(<dependencyManagement>)中使用,用来导入POM类型的依赖。通过import,可以将另一个POM中定义的依赖管理配置应用到当前项目中

  • 作用:引入另一项目的依赖配置,不直接应用于编译、测试或运行时

  • 使用场景:在一个父pom中的dependencyManagement标签中需要导入另一个pom中的dependencyManagement的时候

  • <type>元素用于指定依赖的打包类型,默认依赖是.jar文件,是最常见的依赖类型

  • 示例:

    xml 复制代码
    <dependencyManagement>
    	<dependency>
      	  <groupId>org.example</groupId>
        	<artifactId>example-dependencies</artifactId>
        	<version>1.0</version>
        	<type>pom</type>
        	<scope>import</scope>
    	</dependency>
    </dependencyManagement>

<type>单独使用的场景

  • 指定依赖的类型为POM,表明这是一个POM文件,而不是一个实际的库
  • 这个配置用于将指定POM文件中的依赖管理其他配置引入到当前项目中
xml 复制代码
<dependencies>
    <dependency>
	    <groupId>org.springframework.boot</groupId>
	    <artifactId>spring-boot-dependencies</artifactId>
	    <version>2.7.11</version>
        <type>pom</type>
    </dependency>
</dependencies>

2、依赖传递

假设项目A依赖于库B,而库B依赖于库C,那么当你在项目A中声明依赖库B时,Maven会自动为你将库C也加入到A的类路径中。这就是依赖传递的效果,Maven会递归解析每个依赖的依赖

2.1、依赖传递的作用范围

Maven支持不同的依赖范围(scope)依赖传递的行为会受到这些范围的影响。以下是各范围在依赖传递中的行为:

作用范围 传递性 原因
compile 默认范围,可在编译、运行和测试时使用,传递性强
provided 仅在编译和测试时使用,不会在运行时加入,传递性关闭
runtime 仅在运行时使用,编译时不可用,传递性仍然保留
test 仅在测试时使用,不会传递给其他模块
system 需要手动指定的外部依赖,不能传递
import 仅导入依赖管理 仅用于导入依赖管理,不导入具体依赖

2.2、可选依赖

当你为某个依赖指定<optional>true</optional>时,这个依赖就不会自动传递给下游的依赖(即其他依赖这个项目的项目)。一句话,阻止依赖传递。

xml 复制代码
<!--热部署依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
    <scope>runtime</scope>
    <optional>true</optional>
</dependency>

2.3、依赖冲突与版本控制

Maven通过依赖传递机制可能会引入多个不同版本的同一个库,这时就会发生依赖冲突

依赖冲突优先级规则

  • 首要判断:最短路径优先

  • 再者判断:路径相同时先声明者优先

依赖冲突手动排除

  • 在对依赖冲突默认规则生效的版本不满意时候,可以自己选择手动排除
xml 复制代码
<dependency>
    <groupId>com.xc</groupId>
    <artifactId>project2</artifactId>
    <version>1.0-SNAPSHOT</version>
    <scope>compile</scope>
    <!-- 使用excludes标签配置依赖的排除	-->
    <exclusions>
        <!-- 在exclude标签中配置一个具体的排除 -->
        <exclusion>
            <!-- 指定要排除的依赖的坐标(不需要写version) -->
            <groupId>com.xc</groupId>
            <artifactId>project3</artifactId>
        </exclusion>
    </exclusions>
</dependency>

四、Maven工程构建

项目构建是指将源代码、依赖库和资源文件等转换成可执行或可部署的应用程序的过程,在这个过程中包括编译源代码、链接依赖库、打包和部署等多个步骤。

1、生命周期

Maven的生命周期(Lifecycle)是构建项目的步骤集合,定义了从项目编译到部署的一系列过程。

下面是Maven生命周期及其阶段的表格:

生命周期 阶段 描述
Clean 生命周期 pre-clean 执行清理之前的工作
clean(重点) 移除上一次构建生成的文件
post-clean 执行清理之后的工作
Default 生命周期 validate 验证项目结构和必要信息
initialize 初始化构建状态,例如设置属性
generate-sources 生成源代码(如果需要)
process-sources 处理源代码(如代码增强)
generate-resources 生成资源文件
process-resources 复制并处理资源到输出目录,准备打包
compile(重点) 编译项目main目录下的源代码
process-classes 处理编译后的类文件
generate-test-sources 生成测试源代码
process-test-sources 处理测试源代码
generate-test-resources 生成测试资源
process-test-resources 处理测试资源
test-compile 编译测试代码
test(重点) 运行测试代码
prepare-package 打包前的准备工作
package(重点) 将编译结果打包(如 JAR、WAR)
pre-integration-test 运行集成测试前的准备工作
integration-test 运行集成测试
post-integration-test 集成测试后的清理工作
verify 验证项目是否符合标准
install(重点) 安装包到本地仓库
deploy(重点) 将包发布到远程仓库
Site 生命周期 pre-site 生成站点之前的准备工作
site 生成项目站点文档
post-site 生成站点之后的处理工作
site-deploy 发布生成的站点到服务器
  • 生命周期独立:clean、default和site生命周期彼此独立,执行一个生命周期时,不会自动触发其他生命周期
  • 阶段顺序执行:在一个生命周期内,Maven从最初阶段开始执行,依次运行到你指定的阶段。如果指定了一个中间阶段,之前的所有阶段都会被执行,确保构建流程的完整性和一致性

2、构建命令

需要在包含pom.xml的项目根目录执行Maven构建命令,因为Maven是基于这个文件来读取构建配置、依赖和插件信息的。

命令 描述
mvn compile 编译项目,生成target文件
mvn package 打包项目,生成jar或war文件
mvn clean 清理编译或打包后的项目结构
mvn install 打包后上传到maven本地仓库
mvn deploy 只打包,上传到maven私服仓库
mvn site 生成站点
mvn test 执行测试源码

2.1、常见组合命令

  • mvn clean install:清理项目后,重新构建并将包安装到本地仓库
  • mvn clean package:清理项目后,重新生成可分发的包(如 JAR 或 WAR)

2.2、命令选项

  • -DskipTests:跳过测试,例如:mvn clean install -DskipTests
  • -X:启用详细的调试日志信息,例如:mvn clean install -X
  • -U:强制Maven从远程仓库(包括私服)重新下载依赖,例如:mvn clean install -U
  • -T 1C:使用多线程构建,1C表示使用与CPU核数相同的线程数,例如:mvn clean install -T 1C

3、插件

Maven插件是执行项目构建和管理的实际工具。所有的构建任务(例如编译、测试、打包、部署等)都是由插件来执行的。Maven本身是一个框架,它通过插件来调用具体的功能。

3.1、Maven默认的插件

  • maven-compiler-plugin:用于编译源代码。默认Java1.5版本,可以通过配置更改为其他版本

方式一:并设置source和target版本

java 复制代码
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.8.1</version> <!-- 插件版本 -->
  <configuration>
    <source>1.8</source> <!-- 指定源代码使用的Java版本 -->
    <target>1.8</target> <!-- 指定生成字节码的Java版本 -->
  </configuration>
</plugin>

方式二:使用properties设置全局Java版本

java 复制代码
<!-- properties: 项目属性,通常用来定义全局变量 -->
<properties>
    <!-- Maven 编译器的 Java 源代码版本 -->
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>
  • maven-surefire-plugin:用于运行单元测试,主要是通过 JUnit 或 TestNG
  • maven-jar-plugin:用于创建jar文件。默认把编译后的class文件打包为一个jar文件(只是一个标准的库 JAR,不包含所有的依赖项)
  • maven-install-plugin:用于把生成的工件(JAR、WAR 文件等)安装到本地Maven仓库
  • maven-deploy-plugin:用于将工件发布到远程仓库,供其他开发人员使用
  • maven-site-plugin:用于生成站点文档,通常基于项目的POM文件信息生成报告和文档
  • maven-clean-plugin:用于清除项目生成的文件,例如target目录下的编译输出
  • maven-resources-plugin:用于处理项目中的资源文件(如将资源从 src/main/resources 复制到目标目录)

从idea可视化工具查看maven的默认插件:

3.2、生成微服务可运行jar包

由以上插件maven-jar-plugin可知,默认情况只能生成依赖jar,而不是微服务可执行的jar,一般使用SpringBoot插件spring-boot-maven-plugin,这个插件负责打包微服务为一个可运行的jar包。

xml 复制代码
<!--    SpringBoot应用打包插件-->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>
3.2.1、添加spring-boot-maven-plugin插件后的打包流程
  • 第一步:打包生成普通JAR
    • Maven会使用默认打包插件maven-jar-plugin生成一个普通的JAR文件
    • 标准JAR文件,不可执行,用于依赖作为库或被引用
  • 第二步:生成可执行JAR
    • 将第一步生成的JAR文件重命名为xxx.jar.original文件
    • repackage命令会将应用的所有依赖项(包括嵌入式的 Tomcat、Jetty 或其他服务器)打包进JAR中,并且指定JAR的入口点(即 Main-Class)
    • 可执行的JAR,包含所有依赖和嵌入式服务器,能够独立运行
3.2.2、常规打包方式

pom文件:

xml 复制代码
...
    <groupId>com.xc</groupId>
    <artifactId>springboot-mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
...

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

打包结果:

  • springboot-mybatis-1.0-SNAPSHOT.jar
    • 命名: artifactId + 版本号,用"-"连接
    • 可以使用java -jar xxx直接运行的服务,里面包含依赖的jar
  • springboot-mybatis-1.0-SNAPSHOT.jar.original
    • 去掉后缀.original则是可以被其他项目依赖的jar
3.2.3、进阶打包方式

pom文件:

xml 复制代码
...
    <groupId>com.xc</groupId>
    <artifactId>springboot-mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>
...

    <build>
        <finalName>my-mybatis</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <classifier>exec</classifier>
                    <skip>false</skip>
                </configuration>
            </plugin>
        </plugins>
    </build>

打包结果:

  • my-mybatis.jar:依赖jar,不可执行
  • my-mybatis-exec.jar:可执行依赖
  • <finalName>标签:设置打包的名称,不再使用artifactId + 版本号方式
  • <classifier>标签:设置可运行服务jar的后缀
    • 因为可运行jar有了后缀
    • 所有依赖jar就不会重名,也就不用添加后缀.original
  • <skip>标签:mavn执行插件选择是否跳过,默认false,true则不执行当前插件

3.3、<resources>标签

不写<resources>标签

  • src/main/java非java文件都不会编译
    • target当中的classes和打出的包解压BOOT-INF当中的classes都找不到
  • src/main/resources下的文件都会被编译
    • target当中的classes和打出的包解压BOOT-INF当中的classes都可以找到

<resources>标签只设置src/main/java

  • 假如代码中有xml想加载编译,添加如下
xml 复制代码
<build>
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <filtering>true</filtering>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>
  • <filtering>标签:默认值为false。指定打包时的配置文件其中${}引用会换成直接引用
  • 此时src/main/java中的xml会编译,但是src/main/resource中的所有资源都没有加载
  • 可以理解为:
    • 不加<resource>则默认只加载resource文件
    • 添加<resource>则是加哪个路径,只加载哪个路径的文件

最终方案

  • 如此,java和resources下需要的资源都会加载
xml 复制代码
<build>
	<resources>
		<resource>
			<directory>src/main/java</directory>
			<filtering>true</filtering>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
		<resource>
			<directory>src/main/resources</directory>
			<filtering>true</filtering>
        </resource>
	</resources>
</build>	

Maven生命周期、命令、插件之间的关系

Maven的生命周期定义了项目构建的步骤,每个阶段通过绑定的插件目标执行具体任务。命令用于触发生命周期的某个阶段或直接调用插件目标。三者通过插件绑定阶段、命令触发生命周期,协同完成项目的自动化构建。

五、Maven继承和聚合

1、继承

Maven工程之间,A工程继承B工程。本质上是A工程的pom.xml中的配置继承了B工程中pom.xml的配置

1.1、父项目的pom.xml

  • 父项目是作为顶层项目,包含多个子项目的通用配置。父项目的打包类型是pom
  • 使用dependencyManagement标签配置只对依赖的管理,不导入
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>

    <groupId>com.example</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
            </plugin>
        </plugins>
    </build>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-core</artifactId>
                <version>5.3.9</version>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

1.2、子项目pom.xml

  • 子项目通过在pom.xml中使用<parent>标签指定父项目,从而继承父项目的配置
  • 子项目可以继承父项目的依赖、插件、属性等,也可以在子项目中覆盖父项目的配置
  • 如果子工程坐标中的groupIdversion与父工程一致,那么可以省略
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>

    <parent>
        <groupId>com.example</groupId>
        <artifactId>parent-project</artifactId>
        <version>1.0-SNAPSHOT</version>
        <relativePath>../parent-pom.xml</relativePath> <!-- 相对路径 -->
    </parent>

    <artifactId>child-project</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
    </dependencies>
</project>
1.2.1、<relativePath>标签
  • <relativePath>标签用于在子项目的pom.xml中指定父项目的相对路径
  • 如果父项目位于子项目上一级目录,通常不需要显式指定<relativePath>,Maven会默认使用../pom.xml
  • 在非标准目录结构或父项目位于远程仓库时,使用<relativePath/>忽略远程父项目

2、聚合

Maven聚合是通过在一个主项目的pom.xml文件中使用<modules>标签定义多个子模块来实现的。聚合项目本身的pom.xml文件不会直接生成可执行文件,而是负责将多个子模块集中构建

聚合项目pom.xml:

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>

    <groupId>com.example</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <!-- 列出所有模块 -->
    <modules>
        <module>module-a</module>
        <module>module-b</module>
        <module>module-c</module>
    </modules>
</project>

在这个例子中,聚合项目parent-project聚合了三个子模块module-a、module-b和module-c。通过运行聚合项目的mvn installmvn clean install命令,可以一次性构建这三个子模块。

五、Maven仓库

1、Maven仓库

Maven仓库(Maven Repository)是用于存储管理Maven项目构建过程中所需的依赖库插件以及构件的存储库。

1.1、本地仓库(Local Repository)

本地仓库位于开发者的本地机器上,存储Maven构建过程中下载的所有依赖和插件。当项目构建时,Maven 首先会检查本地仓库中是否已经存在需要的依赖,如果没有,则会从远程仓库或中央仓库下载。

  • 默认路径:~/.m2/repository
  • 特性:缓存下载的依赖,减少重复下载,提高构建速度

settings.xml文件修改本地仓库地址,将中央仓库地址替换为阿里云Maven仓库

xml 复制代码
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0
                              http://maven.apache.org/xsd/settings-1.0.0.xsd">

    <localRepository>/path/to/your/repo</localRepository>

    <mirrors>
        <mirror>
            <id>aliyun-maven</id>
            <mirrorOf>central</mirrorOf>
            <name>Aliyun Maven Repository</name>
            <url>https://maven.aliyun.com/repository/public</url>
            <layout>default</layout>
        </mirror>
    </mirrors>

    <!-- 其他配置 -->
</settings>

1.2、中央仓库(Central Repository)

中央仓库是Maven官方维护的公共仓库,存储了开源项目常用的依赖库。它是Maven的默认远程仓库,当本地仓库中没有找到某个依赖时,Maven会自动从中央仓库下载。

  • 中央仓库地址:https://repo.maven.apache.org/maven2
  • 特性:全球公开访问,涵盖了大量开源项目的库和插件

1.3、远程仓库(Remote Repository)

远程仓库是除了中央仓库,任何其他的远程仓库,包括第三方仓库私有仓库

  • 其中,远程仓库可以分为两种子类型:
    • 快照仓库(Snapshot Repository):用于存储开发中的快照版本,支持不断更新
    • 发布仓库(Release Repository):用于存储稳定的已发布版本,内容不会改变

1.4、Maven仓库的工作原理

  1. 本地仓库查找:Maven 首先从本地仓库查找构建所需的依赖和插件
  2. 远程仓库下载:如果本地仓库没有该依赖,Maven 会从配置的远程仓库或中央仓库下载该依赖,并存储到本地仓库中
  3. 依赖缓存:一旦依赖下载到本地仓库,后续构建中无需再次下载,除非依赖的版本发生变化(如 SNAPSHOT版本)
  4. 发布到仓库:开发人员可以将构件(如打包的JAR文件)发布到远程仓库(如企业私有仓库),供其他团队成员或项目共享使用

2、Maven私服

Maven私服是一种特殊的Maven远程仓库,它是架设在局域网内的仓库服务,用来代理位于外部的远程仓库(中央仓库、其他远程公共仓库)。

以下是搭建 Maven 私服常用的工具:

  • Nexus Repository Manager:由Sonatype提供的开源仓库管理器(当前最流行、使用最广泛)
  • Artifactory:Jfrog提供的仓库管理工具,支持多种格式的包管理(包括 Maven)
  • Apache Archiva:Apache提供的开源工具,专注于Maven仓库管理

2.1、Nexus仓库

仓库类型 说明
proxy 代理仓库:用于从远程存储库获取组件
group 组仓库:它将多个仓库聚合为一个访问入口,可以一并访问多个底层仓库
hosted 托管仓库:用于存储由内部开发者创建的jar包
  • maven-central:代理了远程的Maven中央仓库,构建项目时会从该仓库下载依赖
  • maven-public:一个组仓库,聚合了多个仓库的内容
    • 它将多个仓库整合成一个统一的入口,便于开发者访问
    • 在这个组中,通常包含maven-releasesmaven-snapshotsmaven-central等仓库
    • 那么只需要配置一个maven-public仓库,就能同时访问这些托管的和代理的仓库
  • maven-releases:专门用于存储发布的版本(release versions)的构件
    • 当一个项目发布了稳定的版本(非SNAPSHOT),可以将这些构件发布到maven-releases仓库中
    • 其他团队成员或相关项目可以直接从这个仓库下载发布的版本
  • maven-snapshots:专门用于存储开发中的SNAPSHOT版本的构件
    • SNAPSHOT版本代表开发中的构件,它们可能会频繁更新,不像release版本那样稳定
    • 每次构建的SNAPSHOT版本都会覆盖先前版本,而不是生成新的版本号

2.2、通过Nexus下载jar包

  • 修改settings.xml
java 复制代码
<mirrors>
    <mirror>
        <id>nexus-mirror</id> <!-- 这是镜像仓库的唯一标识符,不用于认证 -->
        <mirrorOf>central</mirrorOf> <!-- 重定向中央仓库的请求 -->
        <url>http://your-nexus-repo-url/repository/maven-public/</url>
    </mirror>
</mirrors>

<servers>
    <server>
        <id>nexus-mirror</id> <!-- 如果上面仓库需要认证,这个ID必须与上面id一致 -->
        <username>your-username</username>
        <password>your-password</password>
    </server>
</servers>
  • url标签的来源
  • 本地仓库下载完包以后,nexus的组仓库maven-public就能看见jar包了
  • 若下载速度太慢,可以设置私服中中央仓库的地址为阿里云仓库地址


2.3、将jar包部署到Nexus

步骤 1:在pom.xml中配置发布仓库

  • 一个用于发布正式的release版本,另一个用于发布snapshot(快照)版本
xml 复制代码
<distributionManagement>
    <repository>
        <id>nexus-releases</id> <!-- 正式发布仓库的 ID -->
        <url>http://your-nexus-repo-url/repository/maven-releases/</url> <!-- Nexus Releases 仓库的 URL -->
    </repository>
    <snapshotRepository>
        <id>nexus-snapshots</id> <!-- 快照仓库的 ID -->
        <url>http://your-nexus-repo-url/repository/maven-snapshots/</url> <!-- Nexus Snapshots 仓库的 URL -->
    </snapshotRepository>
</distributionManagement>

步骤 2:在 settings.xml 中配置认证信息

  • distributionManagement中的仓库id添加相应的认证信息
xml 复制代码
<servers>
    <server>
        <id>nexus-releases</id> <!-- 对应 pom.xml 中的 repository ID -->
        <username>your-username</username>
        <password>your-password</password>
    </server>
    <server>
        <id>nexus-snapshots</id> <!-- 对应 pom.xml 中的 snapshotRepository ID -->
        <username>your-username</username>
        <password>your-password</password>
    </server>
</servers>
  • 上传成功

3、repositories和mirrors

3.1、repositories(仓库)

repositories 是Maven用于查找和下载项目依赖的远程或本地存储库。Maven在构建项目时,会从这些仓库中查找所需的依赖(如 JAR 包)并下载到本地存储库。

主要功能

  • 定义Maven用来查找项目依赖的存储库位置
  • 可以在pom.xml中为每个项目单独配置,也可以在settings.xml中全局配置

示例

pom.xml 中定义仓库:

xml 复制代码
<repositories>
    <repository>
        <id>company-repo</id> <!-- 仓库的唯一 ID,用于认证等 -->
        <url>http://your-company-repo-url/repository/maven-releases/</url> <!-- 仓库 URL -->
        <releases>
            <enabled>true</enabled> <!-- 指定是否用于发布版本 -->
        </releases>
        <snapshots>
            <enabled>false</enabled> <!-- 指定是否用于快照版本 -->
        </snapshots>
    </repository>
</repositories>

3.2、mirrors(镜像)

mirrors 用于对某个特定仓库(如Maven中央仓库)的请求重定向到另一个仓库(如公司内部的Nexus仓库)。它的主要作用是将对中央仓库、快照仓库等的请求重定向到另一个地方。

主要功能

  • 当Maven请求中央仓库时,它会自动将请求转发到定义的镜像仓库,而不需要手动配置每个项目的repositories
  • 配置在settings.xml中(而不是 pom.xml),适用于全局配置

示例

settings.xml 中定义镜像:

xml 复制代码
<mirrors>
    <mirror>
        <id>nexus-mirror</id> <!-- 镜像仓库的唯一标识符 -->
        <mirrorOf>central</mirrorOf> <!-- 指定要镜像的仓库,如 Maven 中央仓库 -->
        <url>http://your-company-repo-url/repository/maven-public/</url> <!-- 镜像仓库的 URL -->
    </mirror>
</mirrors>
  • id:为镜像指定的唯一标识符。它可以是任意值,用于区分不同的镜像配置
  • mirrorOf:定义要镜像的仓库。常见的值包括:
    • central:表示Maven中央仓库
    • *:表示镜像所有仓库
    • repo1,repo2:表示镜像多个指定的仓库
    • !central:表示镜像所有仓库,除了中央仓库
  • url:镜像仓库的实际URL,Maven将通过这个URL下载依赖

3.3、settings.xml配置仓库

  • 本地仓库: 首先查找 localRepository,已有依赖则直接使用
  • 私服仓库: 查找已配置的私服 releases 和 snapshots 仓库,优先满足公司内部依赖
  • 私服插件仓库: 如果依赖为插件类型,则查找 private-plugin-repo
  • 阿里云镜像: 最后查找阿里云中央仓库镜像,加速从中央库获取公共依赖
xml 复制代码
<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">

    <!-- 本地仓库路径: Maven 会将下载的依赖存储在此路径中。
         例如,可以设置为 C:/Users/YourUser/.m2/repository 
         如果不设置,Maven 将使用默认路径 ~/.m2/repository -->
    <localRepository>/path/to/your/local/repo</localRepository>

    <!-- 配置镜像仓库 -->
    <mirrors>
        <!-- 阿里云中央仓库镜像:用于加速 Maven 中央仓库的下载速度。
             id:镜像的唯一标识
             mirrorOf:指定拦截的仓库,此处设置为 "central",表示仅镜像中央仓库
             url:阿里云中央仓库的 URL 地址 -->
        <mirror>
            <id>aliyun-central</id>
            <mirrorOf>central</mirrorOf>
            <url>https://maven.aliyun.com/repository/central</url>
        </mirror>
    </mirrors>

    <!-- 配置私服仓库 -->
    <profiles>
        <profile>
            <id>use-private-repo</id> <!-- 配置的唯一标识,便于激活私服配置 -->

            <!-- 依赖库配置:用于存储公司内部或特定的依赖库 -->
            <repositories>
                <!-- Releases 仓库:用于存储已发布的稳定版本 -->
                <repository>
                    <id>private-repo</id> <!-- 唯一标识,应与认证信息的 id 一致 -->
                    <url>http://your-private-repo-url/repository/maven-releases/</url> <!-- 私服的 URL 地址 -->
                    <releases>
                        <enabled>true</enabled> <!-- 启用 Releases 仓库 -->
                    </releases>
                    <snapshots>
                        <enabled>false</enabled> <!-- 禁用 Snapshots 仓库 -->
                    </snapshots>
                </repository>

                <!-- Snapshots 仓库:用于存储开发中的快照版本 -->
                <repository>
                    <id>private-snapshots</id> <!-- 唯一标识,应与认证信息的 id 一致 -->
                    <url>http://your-private-repo-url/repository/maven-snapshots/</url> <!-- 私服的 URL 地址 -->
                    <releases>
                        <enabled>false</enabled> <!-- 禁用 Releases 仓库 -->
                    </releases>
                    <snapshots>
                        <enabled>true</enabled> <!-- 启用 Snapshots 仓库 -->
                    </snapshots>
                </repository>
            </repositories>

            <!-- 插件库配置:用于存储和下载公司内部或特定的 Maven 插件 -->
            <pluginRepositories>
                <pluginRepository>
                    <id>private-plugin-repo</id> <!-- 唯一标识,应与认证信息的 id 一致 -->
                    <url>http://your-private-repo-url/repository/maven-plugins/</url> <!-- 私服的 URL 地址 -->
                    <releases>
                        <enabled>true</enabled> <!-- 启用 Releases 插件库 -->
                    </releases>
                    <snapshots>
                        <enabled>true</enabled> <!-- 启用 Snapshots 插件库 -->
                    </snapshots>
                </pluginRepository>
            </pluginRepositories>
        </profile>
    </profiles>

    <!-- 激活配置的私服仓库 -->
    <activeProfiles>
        <!-- 指定激活的 profile,与上面配置的 <profile> 标签的 id 匹配 -->
        <activeProfile>use-private-repo</activeProfile>
    </activeProfiles>

    <!-- 配置私服认证信息 -->
    <servers>
        <!-- 配置私服的身份认证信息,以便需要身份验证时能够访问私服仓库 -->
        <server>
            <id>private-repo</id> <!-- 必须与 <repositories> 中的 id 一致 -->
            <username>your-username</username> <!-- 私服用户名 -->
            <password>your-password</password> <!-- 私服密码 -->
        </server>
        <server>
            <id>private-snapshots</id> <!-- 必须与 <repositories> 中的 id 一致 -->
            <username>your-username</username> <!-- 私服用户名 -->
            <password>your-password</password> <!-- 私服密码 -->
        </server>
        <server>
            <id>private-plugin-repo</id> <!-- 必须与 <pluginRepositories> 中的 id 一致 -->
            <username>your-username</username> <!-- 私服用户名 -->
            <password>your-password</password> <!-- 私服密码 -->
        </server>
    </servers>

</settings>
相关推荐
feilieren11 分钟前
leetcode - 684. 冗余连接
java·开发语言·算法
The Future is mine21 分钟前
Java根据word模板导出数据
java·开发语言
一颗甜苞谷34 分钟前
开源一款前后端分离的企业级网站内容管理系统,支持站群管理、多平台静态化,多语言、全文检索的源码
java·开发语言·开源
星夜孤帆35 分钟前
Java面试题集锦
java·开发语言
论迹42 分钟前
【Java】-- 接口
java·开发语言
dawn1912282 小时前
Java 中的正则表达式详解
java·开发语言·算法·正则表达式·1024程序员节
葉A子2 小时前
poi处理excel文档时,与lombok的@Accessors(chain = true)注解冲突
java
鱼跃鹰飞2 小时前
大厂面试真题-简单描述一下SpringBoot的启动过程
java·spring boot·后端·spring·面试
大只因bug2 小时前
基于Springboot的在线考试与学习交流平台的设计与实现
java·spring boot·后端·学习·mysql·vue·在线考试与学习交流平台系统
想进大厂的小王2 小时前
Spring Boot⾃动配置
java·spring boot·后端