Maven
1925字约6分钟
2026-01-22
Maven目录结构
项目根目录/
├── src/ # 源代码和资源的根目录
│ ├── main/ # 主程序代码和资源(生产环境)
│ │ ├── java/ # 主程序 Java 源代码(.java 文件)
│ │ ├── resources/ # 主程序资源文件(配置文件、静态资源等)
│ │ ├── webapp/ # Web 项目专用:Web 资源(HTML、CSS、JS、JSP 等)
│ │ │ └── WEB-INF/ # Web 项目配置(web.xml、Spring 配置等)
│ │ └── filters/ # 资源过滤文件(用于替换资源中的变量)
│ │
│ └── test/ # 测试代码和资源
│ ├── java/ # 测试 Java 源代码(如 JUnit 测试类)
│ ├── resources/ # 测试资源文件(测试用配置、数据等)
│ └── filters/ # 测试资源过滤文件
│
├── target/ # 构建输出目录(自动生成,可删除)
│ ├── classes/ # 编译后的主程序 class 文件
│ ├── test-classes/ # 编译后的测试 class 文件
│ ├── jar/ # 打包生成的 JAR/WAR 等文件
│ └── ...(其他构建中间产物)
│
├── pom.xml # Maven 核心配置文件(项目坐标、依赖、插件等)
└── .gitignore # 版本控制忽略文件(可选,如忽略target/)安装
注意:在安装maven时,要注意idea版本是否与maven兼容
版本:idea2021,maven3.6.2
idea配置(打开设置)

导入依赖项
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>Maven 的依赖传递性
Maven 项目中,当 A 依赖 B,B 依赖 C 时,Maven 会自动将 C 也引入到 A 中(这就是「依赖传递」)。
但如果 C 版本有冲突,或不需要 C 时,就可以通过「排除依赖」手动阻断这种传递,强制不引入特定依赖。
简单说:排除依赖的本质是告诉 Maven:在解析依赖树时,忽略某个传递过来的依赖项。
<dependencies>
<!-- 直接依赖:当前项目依赖 A -->
<dependency>
<groupId>com.example</groupId>
<artifactId>A</artifactId>
<version>1.0.0</version>
<!-- 排除 A 传递过来的依赖 B -->
<exclusions>
<exclusion>
<!-- 必须指定被排除依赖的 groupId 和 artifactId -->
<groupId>com.example</groupId>
<artifactId>B</artifactId>
<!-- 不需要指定版本,因为要排除的是 A 所依赖的所有版本的 B -->
</exclusion>
</exclusions>
</dependency>
</dependencies>Maven 的依赖传递是「层级传递」的:如果 A→B→C(A 依赖 B,B 依赖 C),C 会默认传递到 A 中。
要阻止这种传递,需要在 B 对 C 的依赖声明中添加排除配置,或者在 A 对 B 的依赖声明中排除 C。
方式 1:在 B 的 pom.xml 中排除 C(推荐)
如果 B 是你可以修改的项目,在 B 中声明对 C 的依赖时,添加 <optional>true</optional>,表示 C 是 B 的「可选依赖」,不会自动传递给依赖 B 的项目(如 A)。
<!-- B 项目的 pom.xml -->
<dependencies>
<!-- B 依赖 C,但 C 不会传递给 A -->
<dependency>
<groupId>com.example</groupId>
<artifactId>C</artifactId>
<version>1.0.0</version>
<!-- 关键配置:标记为可选依赖,不传递 -->
<optional>true</optional>
</dependency>
</dependencies>这样,当 A 依赖 B 时,C 不会被自动引入到 A 中,但 B 自身仍可正常使用 C。
方式 2:在 A 的 pom.xml 中排除 C(如果无法修改 B)
如果 B 是第三方依赖(你无法修改其 pom.xml),则在 A 依赖 B 时,显式排除 C:
<!-- A 项目的 pom.xml -->
<dependencies>
<!-- A 依赖 B,但排除 B 传递的 C -->
<dependency>
<groupId>com.example</groupId>
<artifactId>B</artifactId>
<version>1.0.0</version>
<!-- 排除 B 传递过来的 C -->
<exclusions>
<exclusion>
<groupId>com.example</groupId>
<artifactId>C</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>这种方式会强制阻断 C 从 B 传递到 A,但不影响 B 自身对 C 的使用。
依赖使用范围
| 依赖范围 | 核心作用 | 主程序(main文件夹中) | 测试(test文件夹中) | 运行(package指令范围内) | 依赖传递性 | 典型示例 |
|---|---|---|---|---|---|---|
| compile(默认) | 项目核心依赖,全程可见 | ✅ 有效 | ✅ 有效 | ✅ 有效 | 完全传递(子依赖默认继承此范围) | spring-core、mybatis |
| test | 仅测试阶段使用,不参与打包 | ❌ 无效 | ✅ 有效 | ❌ 无效 | 不传递(子项目无法继承) | junit、mockito(测试框架) |
| provided | 编译 / 测试需用,但运行时由环境提供(如服务器) | ✅ 有效 | ✅ 有效 | ❌ 无效 | 不传递 | servlet-api(Tomcat 提供)、jsp-api |
| runtime | 编译不依赖(无需写代码时引入),但测试 / 运行需用 | ❌ 无效 | ✅ 有效 | ✅ 有效 | 传递(子依赖默认继承此范围) | mysql-connector-java(JDBC 驱动)、logback-classic |
<dependencies>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
// 设置依赖使用范围
<scope>test</scope>
</dependency>
</dependencies>生命周期


cmd命令
在项目根目录下执行
mvn clean
mvn compile
mvn test
mvn package
mvn install分模块设计
分模块设置需要先针对模块功能进行设计,在进行编码。不会先将工程开发完毕,在进行拆分
maven-utils(将工具类单独打包出来,后续项目直接引用即可)
.
|-- pom.xml
`-- src
`-- main
|-- java
| `-- com
| `-- mao
| `-- utils
| |-- JwtUtils.java
| `-- YmlFile.java
`-- resourcesmaven-utils中的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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.utils</groupId>
<artifactId>maven-utils</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>maven-utils Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>maven-utils</finalName>
</build>
</project>项目中pom.xml添加maven-utils中的pom.xml的信息,这样就可以引入外部的代码
<dependency>
<groupId>com.utils</groupId>
<artifactId>maven-utils</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>继承


|-- demo1
|-- A
| `-- pom.xml
`-- B
|-- pom.xml
`-- src
`-- main
|-- resourcesA中的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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.a</groupId>
<artifactId>A</artifactId>
<!-- 打包方式-->
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<dependencies>
</dependencies>
<build>
<finalName>A</finalName>
</build>
</project>B中的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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.b</groupId>
<artifactId>B</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<!-- 继承A-->
<!-- A中的所有依赖,B均可使用,不需要重新引入-->
<parent>
<groupId>com.a</groupId>
<artifactId>A</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../A/pom.xml</relativePath>
</parent>
</project>版本锁定

|-- demo1
|-- A
| `-- pom.xml
`-- B
|-- pom.xml
`-- src
`-- main
|-- resourcesA中的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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.a</groupId>
<artifactId>A</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<dependencies>
</dependencies>
<!-- 版本锁定-->
<!-- 父工程中修改版本,子工程中的依赖版本也会跟着变更-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>B中的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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.b</groupId>
<artifactId>B</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<!-- 继承A-->
<!-- A中的所有依赖,B均可使用,不需要重新引入-->
<parent>
<groupId>com.a</groupId>
<artifactId>A</artifactId>
<version>1.0-SNAPSHOT</version>
<relativePath>../A/pom.xml</relativePath>
</parent>
<!-- 父工程中锁定了版本号,子工程中就不需要写版本号-->
<!-- 子工程中的依赖版本和父工程中锁定的依赖版本一致-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>统一设置依赖版本
<!-- 统一设置依赖版本-->
<properties>
<!-- 名字可以自定义-->
<junit.version>3.8.1</junit.version>
</properties>
<!-- 版本锁定-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<!-- 版本锁定-->
<version>${junit.version}</version>
</dependency>
</dependencies>
</dependencyManagement>聚合


|-- demo1
|-- A
| `-- pom.xml
`-- B
|-- pom.xml
`-- src
`-- main
|-- resourcesA中的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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.a</groupId>
<artifactId>A</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<dependencies>
</dependencies>
<!-- 聚合子工程-->
<modules>
<module>../B</module>
</modules>
</project>继承与聚合

私服

