JAVA高级工程师--Maven父子关系专题

一、项目结构

cs 复制代码
project/                           # 第一层:顶级父工程
├── pom.xml                       # 顶级POM (packaging=pom)
├── proCommon/                    # 第二层:公共模块
│   ├── pom.xml                   # 继承 project
│   └── src/
├── proMoudleA/                   # 第二层:模块A父工程
│   ├── pom.xml                   # 继承 project (packaging=pom)
│   ├── a-system/                 # 第三层:系统模块
│   │   ├── pom.xml               # 继承 proMoudleA
│   │   └── src/
│   └── a-business/               # 第三层:业务模块
│       ├── pom.xml               # 继承 proMoudleA
│       └── src/
└── proMoudleB/                   # 第二层:模块B
    ├── pom.xml                   # 继承 project
    └── src/

二、POM 继承关系代码

第一层(父):project/pom.xml

父 POM 的核心职责:父 POM 是项目的 全局配置中心 ,负责统一管理依赖版本、插件版本和公共配置,确保所有子模块的一致性。

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>project</artifactId>
    <version>1.0.0</version>
    <packaging>pom</packaging>

    <!-- 管理所有二级模块 -->
    <modules>
        <module>proCommon</module>
        <module>proMoudleA</module>
        <module>proMoudleB</module>
    </modules>

    <!-- 子模块会自动继承的配置 -->
    <properties>
        <java.version>17</java.version>
        <lombok.version>1.18.30</lombok.version>
    </properties>

    <!-- 全局依赖管理(所有子模块继承,并子模块需要显式声明) -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.30</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <!-- 父 POM -->
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.11.0</version>
                    <configuration>
                        <source>17</source>
                        <target>17</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>

1.依赖管理 (dependencyManagement)

  • 作用:集中定义依赖的版本和范围,子模块引用时无需重复指定版本。一般父工程中才有dependencyManagement

XML 复制代码
 <!-- 全局依赖管理(所有子模块继承) -->
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.30</version>
                <scope>provided</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
dependencyManagement两大核心特性:

1. 声明而非引入 (Declaration, Not Inclusion)

  • 父工程 (dependencyManagement 中声明) :仅仅定义 了依赖的 groupIdartifactIdversion(以及 scopeexclusions 等),相当于一个"依赖版本清单"或"模板"。

  • 子模块不会自动继承这些依赖。子模块的类路径中不会有这些依赖。

  • 实际引入:只有当子模块在自己的 <dependencies>明确声明 了某个依赖(只需 groupIdartifactId),该依赖才会被真正引入到该子模块中。

主要目的统一管理多模块项目中的依赖版本,避免各个子模块重复声明版本号,造成版本不一致。

2. 版本管理策略 (Version Management Strategy)

  • 版本继承 :不指定版本,继承父管理版本。子模块 <dependencies> 中声明依赖时,可以省略 <version> 。此时,将自动使用父工程 <dependencyManagement> 中为该依赖定义的版本。

  • 版本覆盖 :指定版本,覆盖父管理版本。如果子模块在声明依赖时明确指定了 <version> ,那么子模块指定的版本将优先于 (覆盖)父工程 <dependencyManagement> 中定义的版本。

主要目的:在保持整体一致性的前提下,为特殊模块提供灵活的覆盖能力。

2.插件管理 (pluginManagement)

  • 作用:统一插件版本和默认配置,子模块按需启用。

XML 复制代码
 <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.11.0</version>
                    <configuration>
                        <source>17</source>
                        <target>17</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

3.其他公共配置

  • 定义全局属性(如 <properties> 中的 Java 版本)。
  • 声明模块聚合(<modules>)。
XML 复制代码
 <!-- 管理所有二级模块 -->
    <modules>
        <module>proCommon</module>
        <module>proMoudleA</module>
        <module>proMoudleB</module>
    </modules>

第二层(子):proMoudleA/pom.xml

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    
    <!-- 声明父POM:继承顶级父工程 -->
    <parent>
        <groupId>com.example</groupId>
        <artifactId>project</artifactId>
        <version>1.0.0</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    
    <artifactId>proMoudleA</artifactId>
    <packaging>pom</packaging>  <!-- 自身也是父模块 -->
    
    <!-- 管理三级模块 -->
    <modules>
        <module>a-system</module>
        <module>a-business</module>
    </modules>
</project>

第三层(孙):a-business/pom.xml

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    
    <!-- 继承二级父工程 proMoudleA -->
    <parent>
        <groupId>com.example</groupId>
        <artifactId>proMoudleA</artifactId>
        <version>1.0.0</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    
    <artifactId>a-business</artifactId>
    <packaging>jar</packaging>
    
    <!-- 依赖公共模块 proCommon -->
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>proCommon</artifactId>
        </dependency>
    </dependencies>
</project>

三、其他关键点

1.依赖传递

假如proCommon中引入了lombok,a-business需要使用lombok。

依赖传递路径:

TypeScript 复制代码
a-business      →      proCommon     →    lombok
      ↓                   ↓                  ↓
  声明依赖proCommon     声明依赖lombok    从父工程继承版本

a-business自动获得lombok依赖。

2.Scope

jar包的作用域socpe: 一共6种

test 当前依赖仅参与项目的单元测试

runtime 当前依赖仅参与项目的运行阶段

provided 与compile 类似,区别在与不会参与项目的最终打包

system 从本地磁盘中引用一个jar包

(1)如果不设置scope标签,m默认值就是compile

(2)如果作用于是system,那么还需要额外加入一个标签,如下: <scope>import</scope>

TypeScript 复制代码
<!-- compile(默认):会传递 -->
<dependency>
    <scope>compile</scope>
</dependency>

<!-- provided:不传递 -->
<dependency>
    <scope>provided</scope>
</dependency>

<!-- test:不传递 -->
<dependency>
    <scope>test</scope>
</dependency>

<!-- runtime:会传递,但编译时不使用 -->
<dependency>
    <scope>runtime</scope>
</dependency>
TypeScript 复制代码
<!-- 模块A依赖于B(compile) -->
<!-- 模块B依赖于C(runtime) -->
<!-- 结果:A对C的依赖范围是 runtime -->

<!-- 传递规则:
直接依赖范围    间接依赖范围    传递范围
compile        compile        compile
compile        runtime        runtime
runtime        compile        runtime
runtime        runtime        runtime
provided       any            provided(不传递)
test           any            test(不传递)
-->

3.Maven工作流程

TypeScript 复制代码
1. 父POM定义统一版本(dependencyManagement)
2. 子模块继承父POM(<parent>)
3. 子模块声明依赖(不指定版本)
4. Maven解析传递依赖
5. 解决版本冲突(最短路径优先)
<!-- 最短路径优先 -->
模块A → B → C → X:1.0    # 路径长度3
模块A → D → X:2.0        # 路径长度2
结果:选择X:2.0(路径更短)

4.packaing打包

(1)jar

复制代码
✅ 特点:
• 包含编译后的 .class 文件
• 包含资源文件(resources)
• 有 META-INF/MANIFEST.MF
• 是最常见的 Java 包格式

✅ 主要用途:
• Java 应用程序(可执行 JAR)
• 工具类库(供其他项目依赖)
• 微服务应用(Spring Boot)
• 插件或工具包

(2)war

复制代码
✅ 特点:
• 标准 Web 应用打包格式
• 包含 WEB-INF 目录结构
• 可部署到 Servlet 容器(Tomcat、Jetty、WebLogic)
• 包含 web.xml 部署描述符(可选)

✅ 主要用途:
• 传统 Java Web 应用
• Spring MVC 应用
• JSP/Servlet 项目
• 需要部署到外部容器的应用

(3)pom

复制代码
✅ 特点:
• 不生成实际的构建产物(无 JAR/WAR)
• 仅用于管理和配置
• 作为父模块或聚合模块
• 统一管理依赖版本和插件

✅ 主要用途:
• 多模块项目的父 POM
• 企业级项目的 BOM(Bill Of Materials)
• 统一依赖版本管理
• 共享构建配置
相关推荐
imkaifan2 小时前
10、vue3中针对图片的处理
前端·javascript·vue.js
柯南二号2 小时前
【大前端】【iOS】iOS 使用 Objective-C 绘制几大常见布局(UIKit / Core Graphics 实战)
前端·ios
爱干饭的boy2 小时前
MacBook安装node.js/maven/mysql
mysql·node.js·maven
编程小白gogogo2 小时前
苍穹外卖---swagger
java
sinat_255487812 小时前
文件I/O流
java·jvm·算法
invicinble2 小时前
对于使用html去进行前端开发的全面认识,以及过度到vue开发
前端·javascript·vue.js
我这一生如履薄冰~2 小时前
element-plus去除el-dropdown组件当鼠标移入文本时会出现边框
前端·elementui·vue
小果子^_^2 小时前
div或按钮鼠标经过或鼠标点击后效果样式
前端·css·计算机外设
han_2 小时前
前端性能优化之性能瓶颈点,Web 页面加载全流程解析
前端·javascript·性能优化