Maven——Maven开发经验总结(1)

摘要

本文总结了 Maven 开发中的多个关键经验,包括如何根据版本号决定推送到 releases 或 snapshots 仓库,如何在构建过程中跳过测试,父项目如何控制子项目依赖版本,父项目依赖是否能传递到子项目,如何跳过 Maven deploy 中的某个 module,以及 Maven package 时如何跳过测试等,为 Maven 开发提供了实用指南。

1. Maven在运行部署的时候是如何确定推送到Releases还是Snapshots仓库

在 Maven 中,部署到 releasessnapshots 仓库的决定是通过版本号来判断的。具体规则如下:

  1. 版本号规则
    • Release 版本 :如果版本号不包含 -SNAPSHOT 后缀,Maven 会认为这是一个稳定的发布版本,并会推送到 releases 仓库。例如:1.0.0
    • Snapshot 版本 :如果版本号包含 -SNAPSHOT 后缀,Maven 会认为这是一个开发版本,并会推送到 snapshots 仓库。例如:1.0.0-SNAPSHOT
  1. Maven 配置文件( pom.xml**)** : 在你的项目的 pom.xml 文件中,指定仓库的 URL 和仓库的 ID。通常,在 <distributionManagement> 部分,Maven 会配置 releasessnapshots 仓库的地址。例如:

    <distributionManagement> <repository> <id>releases</id> <url>https://repo.maven.apache.org/maven2</url> </repository> <snapshotRepository> <id>snapshots</id> <url>https://oss.sonatype.org/content/repositories/snapshots/</url> </snapshotRepository> </distributionManagement>

在这里,Maven 会根据你的版本号(是否包含 -SNAPSHOT 后缀)决定将构件部署到哪个仓库。

  1. 部署过程
    • 当你执行 mvn deploy 时,Maven 会根据 pom.xml 中的版本号以及配置文件中的仓库信息判断将构件推送到哪个仓库。
    • 对于 SNAPSHOT 版本,Maven 会推送到 snapshots 仓库,并且通常会带有时间戳,允许多个相同版本的构件在同一时间存在。
    • 对于 release 版本,Maven 会推送到 releases 仓库,并且这个版本通常是稳定的,不会再更新。
  1. 推送行为
    • 对于 SNAPSHOT 版本,Maven 会允许在推送时覆盖同一版本号的构件(如:同一版本的 1.0.0-SNAPSHOT 可以被不同的构建替换),这使得开发过程中可以频繁更新。
  • 对于 release****版本,推送到 releases****仓库时,版本号必须是唯一的,不允许覆盖已发布的版本。

总结来说,版本号的后缀决定了推送目标仓库

  • -SNAPSHOT 推送到 snapshots 仓库。
  • 不含 -SNAPSHOT 的版本推送到 releases 仓库。

2. Maven在构建过程中跳过测试

复制代码
<build>
  <pluginManagement>
    <plugins>
      <plugin>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
          <!-- 跳过测试 -->
          <skip>true</skip>
        </configuration>
      </plugin>
    </plugins>
  </pluginManagement>
</build>

2.1. Maven Surefire Plugin 的作用

  • Maven Surefire Plugin 是 Maven 的核心插件之一,用于执行单元测试。
  • 默认情况下,Maven 在构建项目时会自动运行 src/test/java 目录下的测试类。
  • 通过配置 <skip>true</skip>,可以跳过测试阶段,从而加快构建速度。

2.2. 实际应用场景

  1. 加快构建速度: 在开发过程中,如果不需要运行测试,可以通过跳过测试来加快构建速度。
  2. 跳过失败的测试: 如果某些测试暂时失败,但需要继续构建项目,可以通过跳过测试来避免构建失败。
  3. 配置统一管理 : 在大型项目中,可以通过 <pluginManagement> 集中管理插件配置,确保所有子项目使用相同的插件行为。

2.3. 注意事项

  • 如果需要强制跳过测试,可以在命令行中直接使用 -DskipTests 参数,例如:

    mvn clean install -DskipTests

  • 如果只是跳过测试的编译,可以使用 -Dmaven.test.skip=true 参数,例如:

    mvn clean install -Dmaven.test.skip=true

3. Maven 项目中父项目pom 控制子项目pom的依赖版本吗?

是的,在 Maven 项目中, pom.xml 可以控制 子模块 ( sub-modules**)** 的依赖版本,主要有两种方式:

3.1. 使用 **<dependencyManagement>**统一管理版本

推荐做法 :在 pom.xml 里使用 <dependencyManagement> 只定义依赖版本,子模块在引入时不需要指定版本。

3.1.1. 父项目 pom.xml

复制代码
<project>
  <groupId>com.example</groupId>
  <artifactId>parent-project</artifactId>
  <version>1.0.0</version>
  <packaging>pom</packaging>

  <modules>
    <module>sub-module-a</module>
    <module>sub-module-b</module>
  </modules>

  <dependencyManagement>
    <dependencies>
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.7.5</version>  <!-- 统一管理版本 -->
      </dependency>
    </dependencies>
  </dependencyManagement>
</project>

3.1.2. 子项目 pom.xml**(无需指定版本)**

复制代码
<project>
  <parent>
    <groupId>com.example</groupId>
    <artifactId>parent-project</artifactId>
    <version>1.0.0</version>
  </parent>

  <artifactId>sub-module-a</artifactId>

  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>
</project>

3.1.3. 优势

  • 子模块无需指定版本 ,版本由父 pom.xml 控制,保证一致性。
  • 便于升级依赖 ,只需修改父 pom.xml 中的版本号。

3.2. 直接在 **<dependencies>**中定义(不推荐)

如果在 pom.xml 里直接写 <dependencies>,那么子模块会继承这些依赖,但子模块如果有自己的版本,可能会发生冲突

3.2.1. 父项目 pom.xml

复制代码
<project>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>2.7.5</version>  <!-- 子模块会自动继承 -->
    </dependency>
  </dependencies>
</project>

3.2.2. 子项目 pom.xml

复制代码
e<project>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
  </dependencies>
</project>

3.2.3. ⚠️ 缺点

  • 子模块无法单独管理依赖版本,可能会与其他依赖冲突。
  • 如果子模块也指定了版本,可能导致版本不一致(依赖冲突)。

3.3. Maven父子项目依赖管理总结

|-----------------|-------------------------------------|----------------------------------|
| 方式 | 方式 1(✅ 推荐) <dependencyManagement> | 方式 2(⚠️ 不推荐) 直接 <dependencies> |
| 子模块是否需要指定版本 | 不需要,父 POM 控制 | 需要,如果不指定可能继承 |
| 子模块能否覆盖版本 | 可以,但默认使用父 POM 版本 | 可以,但可能会版本冲突 |
| 适合多模块项目 | ,能确保版本统一 | ,易发生版本冲突 |

最佳实践

  • 在父 pom.xml****里使用 **<dependencyManagement>**统一管理版本
  • 子模块只声明依赖,不要指定版本,避免版本混乱。

这种方式适用于 Spring Boot、MyBatis、Dubbo 等大部分多模块 Maven 项目,能提高维护性和稳定性。🚀

4. 父项目Maven依赖是否可以传递到子项目

一个项目引用了nacos的依赖,这个项目中依赖jar 也使用naocs的配置,请问这个的jar 在打包的时候是否需要使用ncos依赖 进行package 。

在你的项目中,如果引用了 Nacos 作为依赖,并且其他 jar 包也使用了 Nacos 配置,通常来说,这些 jar 包在打包时是否需要包含 Nacos 依赖,取决于你对项目的构建方式和依赖管理的配置。

4.1. 依赖传递(Transitive Dependency):

如果你在主项目中引用了 Nacos 的依赖,并且这个主项目的 jar 包会包含并传递 Nacos 依赖给其他模块,那么其他 jar 包在打包时通常 不需要再单独引用 Nacos,主项目中的 Nacos 依赖会被自动引入。这种情况通常适用于基于 Maven 或 Gradle 构建的项目,依赖会在构建时被传递。

例如 ,在 Maven 项目中,Nacos 的依赖应该已经在父项目的 pom.xml 中声明:

复制代码
<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>2.x.x</version>
</dependency>

4.2. 独立打包(Standalone Packaging)

如果你要将某些 jar 包独立打包为单独的应用,且这些应用需要独立引用 Nacos 依赖(例如,一个 jar 作为微服务应用单独运行),那么这些 jar 在打包时可能需要单独包含 Nacos 依赖。你可以通过使用 shade 插件(Maven)或其他类似的工具,将所有依赖都打包进最终的 jar 包中。

示例: Maven 中使用 maven-shade-plugin

复制代码
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-shade-plugin</artifactId>
    <version>3.x.x</version>
    <executions>
        <execution>
            <phase>package</phase>
            <goals>
                <goal>shade</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <artifactSet>
            <excludes>
                <exclude>com.alibaba.nacos:nacos-client</exclude> <!-- 排除某些依赖 -->
            </excludes>
        </artifactSet>
    </configuration>
</plugin>

4.3. 使用 provided 作用域

如果 Nacos 只在运行时需要(例如在容器或框架中自动注入),你可以将 Nacos 依赖的作用域设置为 provided。这样,Nacos 不会被打包进最终的 jar 中,而是在运行时由外部环境提供。

例如 ,在 Maven 中设置 Nacos 依赖为 provided

复制代码
<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>2.x.x</version>
    <scope>provided</scope>
</dependency>

4.4. 依赖的 jar 包直接引用 Nacos

如果某些 jar 包本身直接引用了 Nacos,那么它们在编译时会自动将 Nacos 依赖引入。当这些 jar 被打包时,它们会将这些依赖一起打包。如果你使用 fat jaruber jar 方式打包,这些依赖也会被包括进去。

4.5. 依赖传递总结

  • 如果你依赖的 jar****包已经在主项目中引用了 Nacos ,且你使用的是 Maven 或 Gradle 等构建工具,通常 不需要再次单独引入 Nacos
  • 如果你希望 独立打包并包含 Nacos ,可以使用 shade 插件或者类似的工具。
  • 若 Nacos 仅用于运行时而不需要打包到 jar 中,可以使用 provided 作用域。

根据项目的具体需求和构建方式,你可以选择适合的方式来管理 Nacos 依赖。

5. Maven deploy跳过某个module解决办法

在使用 Maven 时,如果你希望跳过某个模块的 deploy 操作(即不将某个模块部署到远程仓库),可以通过以下几种方法来实现:

5.1. 方法 1:使用 -pl 参数(指定要部署的模块)

你可以使用 -pl 参数来指定需要部署的模块列表,跳过不需要部署的模块。比如,假设你有一个多模块项目,其中有一个模块你不想部署,可以通过指定其它模块来跳过这个模块的部署。

复制代码
mvn deploy -pl !module-to-skip
  • -pl:指定要构建或部署的模块。
  • !module-to-skip:通过 ! 语法排除 module-to-skip 模块。

5.2. 方法 2:在 pom.xml 中使用 profiles 配置

你可以在 pom.xml 文件中定义一个专门的 Maven profile,并在该 profile 中排除某些模块的构建或部署。通过在构建时激活该 profile 来跳过某个模块。

示例:在父 pom.xml 中配置一个 deploy-skip profile,指定不部署某个模块:

复制代码
<profiles>
  <profile>
    <id>deploy-skip</id>
    <modules>
      <module>module1</module>
      <module>module2</module>
      <!-- 排除 module-to-skip -->
    </modules>
  </profile>
</profiles>

然后通过 -P 参数激活该 profile:

复制代码
mvn deploy -Pdeploy-skip

这种方法适用于你有多个环境或配置,并且希望在不同的构建配置下部署不同的模块。

5.3. 方法 3:跳过特定的模块构建和部署

如果你希望完全跳过某个模块的构建或部署,可以通过设置 skip 配置,跳过该模块的构建或 deploy 生命周期。例如,如果某个模块的构建时间较长,或因其他原因不需要部署,可以在其 pom.xml 中添加以下配置来跳过部署:

复制代码
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-deploy-plugin</artifactId>
      <version>3.0.0-M1</version>
      <configuration>
        <skip>true</skip>
      </configuration>
    </plugin>
  </plugins>
</build>

5.4. 方法 4:使用 maven-skip-plugin

有时候,如果你只是想简单地跳过某个模块的构建或 deploy,你可以使用 maven-skip-plugin 插件。在父 pom.xml 或模块 pom.xml 中添加以下配置,来跳过特定模块的 deploy 阶段。

示例:

复制代码
<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-deploy-plugin</artifactId>
    <version>3.0.0</version>
    <configuration>
      <skip>true</skip>
    </configuration>
  </plugin>
</plugins>

5.5. 方法 5:临时跳过 deploy 阶段

如果你不想部署某个模块,但又不希望修改 pom.xml 或配置,可以临时使用 -DskipDeploy 来跳过部署:

复制代码
mvn deploy -DskipDeploy

5.6. 方法 6:使用 mvn install 而不是 deploy

如果你在某个模块不需要将其部署到远程仓库,只是本地构建并安装到本地仓库,可以使用 install 代替 deploy

复制代码
mvn install

这样该模块会被安装到本地仓库,而不会部署到远程仓库。

6. Maven package 的时候跳过测试。

在使用 mvn package 时,如果你希望跳过测试阶段(即不执行单元测试),可以通过以下几种方式来实现:

6.1. 使用 -DskipTests 参数

这是最常用的方式,使用 -DskipTests 参数来跳过测试的执行。该命令只会跳过测试的执行,而不会跳过编译测试代码。

复制代码
mvn package -DskipTests
  • -DskipTests:跳过测试执行,测试代码会被编译,但不会运行。

6.2. 使用 -Dtest=false 参数

另一种方式是使用 -Dtest=false 参数,这会告诉 Maven 不执行任何测试。

复制代码
mvn package -Dtest=false
  • -Dtest=false:强制不执行测试,不会运行任何测试类。

6.3. 使用 -Dmaven.test.skip=true 参数

如果你希望完全跳过测试,包括测试代码的编译和执行,可以使用 -Dmaven.test.skip=true 参数。这会跳过测试的所有阶段,包括编译和执行测试。

复制代码
mvn package -Dmaven.test.skip=true
  • -Dmaven.test.skip=true:完全跳过测试阶段(包括测试的编译和执行)。

6.4. 在 pom.xml 中配置跳过测试

如果你希望在构建过程中总是跳过测试,可以在 pom.xml 中配置跳过测试的属性。

pom.xml 文件中添加以下配置:

复制代码
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>3.0.0-M5</version>
      <configuration>
        <skipTests>true</skipTests>
      </configuration>
    </plugin>
  </plugins>
</build>

6.5. Maven跳过总结

  • 使用 -DskipTests:跳过测试执行,但编译测试代码。
  • 使用 -Dtest=false:完全跳过测试,不执行任何测试类。
  • 使用 -Dmaven.test.skip=true:完全跳过测试的编译和执行。
  • pom.xml 中配置 maven-surefire-plugin,永久跳过测试。

博文参考

相关推荐
开开心心就好16 小时前
高效全能PDF工具,支持OCR识别
java·前端·python·pdf·ocr·maven·jetty
shane-u2 天前
Maven私服搭建与登录全攻略
java·maven
半部论语2 天前
jdk多版本切换,通过 maven 指定编译jdk版本不生效,解决思路
java·开发语言·maven·intellij-idea
我喜欢山,也喜欢海2 天前
Jenkins Maven 带权限 搭建方案2025
java·jenkins·maven
kaikaile19952 天前
Jenkins集成Maven
servlet·jenkins·maven
.生产的驴2 天前
Docker 部署Nexus仓库 搭建Maven私服仓库 公司内部仓库
java·运维·数据库·spring·docker·容器·maven
.生产的驴2 天前
Maven 公司内部私服中央仓库搭建 局域网仓库 资源共享 依赖包构建共享
java·maven
Brilliant Nemo2 天前
五、框架实战:SSM整合原理和实战
maven·mybatis
亮1112 天前
GITLAB跑gradle项目 不借助maven-publish直接上传到nexus私人仓库
java·gitlab·gradle·maven
极小狐2 天前
极狐GitLab 通用软件包存储库功能介绍
java·数据库·c#·gitlab·maven