当前位置: 首页 > news >正文

什么是 Maven?关于 Maven 的命令、依赖传递、聚合与继承

目录

九、Maven 命令

1. 执行 Maven 命令的三种方式

(1)右侧 Maven 窗口的 Lifecycle

(2)命令行窗口(定位到 pom.xml 所在目录)

(3)Windows 自带的 CMD

2. Maven 命令的生命周期

十、依赖传递(Dependency Transitivity)

1. 什么是依赖传递

举例:

2. 会传递 / 不会传递

3. 控制传递

4. WAR 包不能被其他项目依赖

十一、依赖排除与查看依赖链

1. 依赖排除(Exclusion)

方法 1:直接添加自己的依赖

方法 2:排除传递进来的依赖

2. 通过依赖图查看依赖链

方法 1:命令行查看依赖树

方法 2:使用 IDEA 的依赖图(图形界面)

十二、Maven聚合

十三、Maven 继承


九、Maven 命令

1. 执行 Maven 命令的三种方式

在实际项目中,我们通常有三种方式来手动执行 Maven 的编译、打包等命令

(1)右侧 Maven 窗口的 Lifecycle

         在 IntelliJ IDEA 中,右侧有一个 Maven 工具栏,展开项目后,可以看到 Lifecycle 节点。
双击对应阶段(例如 clean、package、install)即可执行命令。

(2)命令行窗口(定位到 pom.xml 所在目录)

打开终端(或 IDEA 的 Terminal),进入包含 pom.xml 的目录,执行例如:

mvn clean packagemvn compilemvn install

在编译过程中,出现了:不再支持源选项 5。请使用 7 或更高版本。

这是因为 Maven 默认使用的 maven-compiler-plugin 插件版本较老,默认的 Java 语言级别是 1.5,而 JDK 17 已不再支持这么低的版本。

解决办法是在 pom.xml 中手动配置 Maven 编译插件:

<build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version><configuration><source>17</source>   <!-- 指定 Java 源码版本 --><target>17</target>   <!-- 指定编译输出版本 --><encoding>UTF-8</encoding></configuration></plugin></plugins></build>

这样 Maven 会使用与本地 JDK 一致的编译版本,避免不兼容问题。

然后就能编译成功了:

(3)Windows 自带的 CMD

       在 Windows 环境下,也可以使用系统自带的 cmd,先进入项目路径,再执行对应的 Maven 命令:

cd D:\work\demo_web1
mvn clean install

出现

这个问题也是因为 Maven 自带的 maven-war-plugin 版本太老(2.2),和当前使用的 JDK 17 + Maven 3.8.8 存在不兼容问题。

所以在pom.xml文件中加入:

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-war-plugin</artifactId><version>3.3.2</version>
</plugin>

此时,再次运行:

Maven 的常用命令都有默认插件,不需要手动配置。但当使用高版本 JDK 或需要特殊构建行为时,手动在 pom.xml 中指定对应插件的版本和配置是非常推荐的做法,尤其是 maven-compiler-plugin 和 maven-war-plugin 两个,能避免 90% 的兼容性报错。


2. Maven 命令的生命周期

Maven 的命令执行遵循生命周期(Lifecycle),分为以下三大类:

生命周期

作用

clean

清理项目(删除 target/ 目录)

default

构建项目(编译、测试、打包、安装、部署)

site

生成项目报告站点

在默认构建生命周期中,包含一系列阶段:

阶段(Phase)

说明

validate

验证项目是否正确

compile

编译主代码

test

编译并执行单元测试

package

打包成 jar/war 文件

verify

对集成测试结果进行验证

install

将构建好的包安装到 本地仓库

deploy

将包发布到远程仓库(如 Nexus)

例如执行:

mvn package

实际上会自动执行:validate → compile → test → package 这些阶段。

而执行:

mvn install

会在打包完成后,将生成的 jar/war 安装到本地 Maven 仓库中,供其他项目依赖使用。


3. 常用 Maven 命令一览

命令

作用

mvn clean

清理项目

mvn compile

编译主程序

mvn test

执行单元测试

mvn package

打包项目

mvn install

安装到本地仓库

mvn deploy

发布到远程仓库

mvn dependency:tree

查看依赖树

mvn spring-boot:run

启动 Spring Boot 项目


4. 依赖范围(Scope)

在 Maven 中,依赖通过 <scope> 标签来控制依赖的使用范围。不同的范围决定依赖在 编译、测试、打包 过程中的可用性

Scope

编译(main)

测试(test)

打包(运行)

常见场景

compile(默认)

普通依赖

provided

×

Servlet API、Tomcat 等容器提供的

runtime

×

JDBC 驱动、反射加载类

test

×

×

JUnit、Mockito

system

×

本地系统路径 jar(不从仓库下载)

示例:

<dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter-api</artifactId><version>5.9.2</version><scope>test</scope></dependency>

即使所有依赖都设置为 compile,项目功能也能正常运行。

合理设置 scope 可以让依赖更清晰,避免打包时引入多余 jar。

使用依赖时,推荐直接在中央仓库搜索坐标粘贴,在IDE 输入也会自动提示 scope。


十、依赖传递(Dependency Transitivity)

Maven 的一大特色就是依赖传递机制。它能够让项目自动引入间接依赖,减少了大量重复的依赖声明。但同时,如果不加以控制,也可能带来版本冲突或引入不必要的包。

1. 什么是依赖传递

假设有两个模块:

A 模块

B 模块

A 想要使用 B 的功能,需要在 A 的 pom.xml 中引入 B:

<!-- A 的 pom.xml -->
<dependencies><dependency><groupId>com.example</groupId><artifactId>module-b</artifactId><version>1.0.0</version></dependency>
</dependencies>

A 依赖 B 时,必须确保 B 先被安装到本地仓库(mvn install),否则 A 会找不到该依赖。

举例:

我把 demo_web1 项目当作A模块,hello 项目当作B模块

在hello 的pom.xml中添加:

<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.3.0</version></dependency>

此时:

然后 install hello

再去 demo_web1 里面添加 hello 的依赖:

此时依赖就传递过来了


2. 会传递 / 不会传递

Maven 的依赖传递默认是开启的,也就是说,依赖默认会传递。
但有些特殊的 scope 会阻止依赖传递:

scope 值

是否传递依赖

说明

compile(默认)

 会传递

常规依赖,默认行为

provided

不会传递

表示运行时由容器(如 Tomcat)提供,编译期可用

test

 不会传递

仅在测试代码中使用

runtime

会传递

编译时不需要,运行时需要

system

不会传递

本地系统路径依赖,不会传递

例如:

在 hello 里面添加依赖:

但是在 demo_web1 里面没有出现相关依赖:


3. <optional> 控制传递

除了 scope,还可以使用 <optional> 来显式控制依赖是否被传递:

<dependency><groupId>com.example</groupId><artifactId>some-lib</artifactId><version>1.0.0</version><optional>true</optional>
</dependency>

<optional>true</optional>:不传递

<optional>false</optional>(默认):传递

小技巧:optional 通常用于避免对下游项目强制引入一些不必要的库。


4. WAR 包不能被其他项目依赖

一个常见的误区是:将某个 Web 项目(<packaging>war</packaging>)当成依赖去引用,这是 不被 Maven 允许的

<!-- 错误:A 不能依赖一个 war 类型的模块 -->
<dependency><groupId>com.example</groupId><artifactId>web-module</artifactId><version>1.0.0</version><type>war</type>
</dependency>

原因:

WAR 是部署包,而不是库包(Jar)
WAR 包包含完整的 Web 应用结构(如 /WEB-INF/lib、HTML、JSP、Servlet 配置等),是要部署到 Web 容器(Tomcat、Jetty)中运行的。
而依赖机制是为编译或运行时加载类和资源设计的,依赖的应该是 jar 类型的可复用代码。

Maven 构建时不会把 WAR 当作 classpath 依赖
它不会把 WAR 包中的 WEB-INF/classes 或 lib 自动加到编译路径,因此引用 WAR 会导致编译/打包出错。

正确做法:

如果希望共享 WAR 中的业务逻辑,应该将公共代码从 WAR 中抽取成一个 独立的 Jar 模块:

common-utils(jar) ← 公共业务逻辑↑web-app(war)admin-app(war)

两个 Web 项目都依赖这个 common-utils 模块,这样结构清晰,依赖关系合理。


十一、依赖排除与查看依赖链

1. 依赖排除(Exclusion)

场景:传递进来的依赖版本过旧,或者与你的版本冲突

例如:

我的 demo_web1中,传递引入了mysql-connector-j:8.3.0

方法 1:直接添加自己的依赖
  <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>9.1.0</version></dependency>

那么此时:

 Maven 会采用 “就近原则” + “声明优先”:
如果同一个依赖在多个地方出现,会优先使用你项目自己声明的版本,覆盖掉传递进来的版本。


方法 2:排除传递进来的依赖

如果确定不希望三方包传递 MySQL,可以这样写:

此时就没有了:mysql-connector-j:8.3.0

这样就能精准控制依赖的内容,避免版本冲突。


2. 通过依赖图查看依赖链

当项目依赖越来越多时,有些依赖并不是你直接引入的

方法 1:命令行查看依赖树

在项目根目录执行:

mvn dependency:tree

这样就能一眼看到是哪一条依赖链引入了不需要的依赖。


方法 2:使用 IDEA 的依赖图(图形界面)

在 IntelliJ IDEA 里,也可以更直观地查看依赖关系:

右键点击 pom.xml → Diagrams → Show Diagram

就会显示依赖图

打开依赖图后,按下 Ctrl + F 搜索你要排查的依赖

IDEA 会高亮出它的来源,你可以沿着箭头反查是谁带进来的

想单独查看某个依赖链,可以在图中点击该依赖,选择Show Paths 或 Show Neighbours of Selected  Nodes


IDEA 就会只显示这条链路


十二、Maven聚合

Maven 聚合是一种用于管理多个子项目的项目组织方式。聚合项目本身不包含业务代码,它的主要作用是统一管理构建和模块顺序。

首先,先创建一个父项目,parent

可以删除 src目录,因为聚合项目通常不编写实际代码,因此不需要 src 目录。


聚合项目的 pom.xml 需要将 packaging 修改为 pom:

  <packaging>pom</packaging>

 在parent里面创建两个模块,aChild 和bChild

此时,要管理子模块,通过 <modules> 标签声明子项目

对于项目间的依赖就不用再install,就能感知到另一个项目的依赖

我在aChild 的 pom.xml 里面添加 bChild 的坐标信息

在bChild的pom.xml中引入依赖:

此时,刷新Maven,aChild中同样引入了依赖


当执行父聚合项目的编译命令(如 mvn clean install)时,所有子项目会按顺序编译。


十三、Maven 继承

Maven 继承是一种更高级的项目管理机制,它不仅管理模块,还能共享依赖、插件和配置。继承在功能上是聚合的增强版。

在 parent 里面添加了依赖,可以看到 aChild 和 bChild 都没有出现依赖

需要在两个子项目里面配置:

此时,就有了继承关系

同时,当使用了继承的方式,那么<groupId> 和 <version> 都会继承自父Maven

对于不是每个子项目都需要的依赖,就在父项目使用<dependencyManagement>

然后在子项目中,按需声明

 或者在一开始创建项目的时候,选择好父项目,那么就会自动创建好相应的继承关系。

http://www.dtcms.com/a/453126.html

相关文章:

  • nat静态地址转化
  • 计算机网站开发要考什么证竞价培训班
  • 《算法与数据结构》第七章[算法3]:图的最小生成树
  • 文科和理科思维差异:推演与归纳
  • 雨雪“开关式”监测:0.5秒精准响应,守护户外安全
  • 做文化传播公司网站手机建立网站
  • HTML的本质——网页的“骨架”
  • 徐州双语网站制作wordpress 外链视频
  • React 快速入门:菜谱应用实战教程
  • 网站备案和域名备案网页源码app
  • Tomcat本地部署SpringBoot项目
  • 大模型开发 - 04 QuickStart_DeepSeek 模型调用流程源码解析:从 Prompt 到远程请求
  • 怎么把在微企点做响应式网站深圳专业网站建
  • 认识三极管
  • gRPC从0到1系列【23】
  • Element Plus 完整教程:从背景到实践
  • Qt编写上下界面切换效果/前进到下一个界面/后退到上一个页面/零件工艺及管理设计系统
  • 第3章 多线程服务器的适用场合与常用编程模型
  • 网站开发什么课程佛山建站模板制作
  • Lua语法(2)
  • npm、npx、pnpm 深度解析:从原理到实战的全方位指南
  • Qt Qml Drag and Drop-鼠标拖动添加组件
  • 神经网络之为什么回归任务的输出是高斯分布的均值
  • 《深入理解 Django 中间件:请求-响应生命周期与执行顺序全解析》
  • HC32项目搭建
  • 台式真空共晶炉口碑企业
  • 网站开发宣传标语网站建设基本情况
  • [效率]学习哔哩哔哩视频的的笔记|对于书签的想法思考
  • 网站一级页面标题怎么做wordpress js库
  • Python 数字类型与类型转换