文章目录
1. 父 POM 的核心职责
父 POM 是项目的 全局配置中心,负责统一管理依赖版本、插件版本和公共配置,确保所有子模块的一致性。
1.1 依赖管理 (dependencyManagement
)
作用:集中定义依赖的版本和范围,子模块引用时无需重复指定版本。
示例:
<!-- 父 POM --> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>3.1.5</version> </dependency> </dependencies> </dependencyManagement>
1.2 插件管理 (pluginManagement
)
作用:统一插件版本和默认配置,子模块按需启用。
示例:
<!-- 父 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>
1.3 其他公共配置
- 定义全局属性(如
<properties>
中的 Java 版本)。 - 声明模块聚合(
<modules>
)。<modules> <module>auth</module> <module>gateway</module> <module>modules</module> <module>api</module> <module>common</module> </modules>
2. 子模块 POM 的核心职责
子模块 POM 负责 具体模块的实现配置,继承父 POM 的依赖和插件模板,并按需覆盖或扩展。
2.1 依赖声明 (dependencies
)
规则:
- 如果依赖在父 POM 的
dependencyManagement
中定义,子模块只需声明groupId
和artifactId
。 - 如果依赖未在父 POM 中定义,需在子模块中完整声明(含版本)。
- 如果依赖在父 POM 的
示例:
<!-- 子模块 POM --> <dependencies> <!-- 继承父 POM 的版本 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 独立声明新依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>2.0.33</version> </dependency> </dependencies>
2.2 插件启用与覆盖 (plugins
)
规则:
- 如果插件在父 POM 的
pluginManagement
中定义,子模块只需声明插件坐标即可继承配置。 - 子模块可覆盖父 POM 的插件配置(如修改参数、绑定生命周期)。
- 如果插件在父 POM 的
示例:
<!-- 子模块 POM --> <build> <plugins> <!-- 继承父 POM 的编译插件配置 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> <!-- 覆盖父 POM 的配置 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> <!-- 禁用测试 --> </configuration> </plugin> </plugins> </build>
3. 核心对比表
配置项 | 父 POM | 子模块 POM |
---|---|---|
依赖管理 | <dependencyManagement> 定义版本 |
<dependencies> 声明具体依赖 |
插件管理 | <pluginManagement> 定义版本和配置 |
<plugins> 启用插件或覆盖配置 |
版本控制 | 集中管理,避免冲突 | 继承父版本或独立声明 |
配置覆盖 | 不可覆盖 | 可覆盖父 POM 的配置(如插件参数) |
强制性 | 可选(但推荐) | 必须显式声明需要的依赖或插件 |
4. 使用场景示例
场景 1:统一管理 Spring Boot 依赖
父 POM:
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>3.1.5</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
子模块:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
场景 2:覆盖插件配置
父 POM:
<pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.2.1</version> <configuration> <skipTests>false</skipTests> </configuration> </plugin> </plugins> </pluginManagement>
子模块:
<plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <configuration> <skipTests>true</skipTests> <!-- 覆盖父 POM 配置 --> </configuration> </plugin> </plugins>
5. 最佳实践
- 父 POM 原则:
- 仅在
dependencyManagement
和pluginManagement
中定义版本,不直接使用<dependencies>
或<plugins>
。 - 通过
<properties>
统一管理版本号,避免硬编码。
- 仅在
- 子模块原则:
- 仅声明需要的依赖和插件,避免冗余配置。
- 覆盖父 POM 配置时需明确标注(如注释说明)。
- 版本一致性:
- 公共依赖(如 Spring Boot、Lombok)应在父 POM 中统一管理。
- 业务特定依赖(如某个工具类库)可在子模块中独立声明。
6:总结
- 父 POM 是 模板,负责定义“用什么版本”。
- 子模块 POM 是 实例,负责声明“具体用哪些”。
- 通过合理分工,既能保证一致性,又能满足模块个性化需求。
7:完整父子pom实例
1、父pom
<?xml version="1.0" encoding="UTF-8"?>
<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.wkl</groupId>
<artifactId></artifactId>
<version>3.6.5</version>
<name></name>
<url>http://www..vip</url>
<description>开发系统</description>
<properties>
<version>3.6.5</version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-boot.version>2.7.18</spring-boot.version>
<spring-cloud.version>2021.0.9</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.6.1</spring-cloud-alibaba.version>
<spring-boot-admin.version>2.7.16</spring-boot-admin.version>
<tobato.version>1.27.2</tobato.version>
<kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>2.0.0</pagehelper.boot.version>
<druid.version>1.2.23</druid.version>
<namic-ds.version>4.3.1</namic-ds.version>
<commons.io.version>2.13.0</commons.io.version>
<velocity.version>2.3</velocity.version>
<fastjson.version>2.0.53</fastjson.version>
<jjwt.version>0.9.1</jjwt.version>
<minio.version>8.2.2</minio.version>
<poi.version>4.1.2</poi.version>
<springdoc.version>1.6.9</springdoc.version>
<transmittable-thread-local.version>2.14.4</transmittable-thread-local.version>
<org.mapstruct.version>1.6.3</org.mapstruct.version>
<hutool.version>5.8.25</hutool.version>
<lombok.version>1.18.30</lombok.version>
<!-- override dependency version -->
<tomcat.version>9.0.98</tomcat.version>
<logback.version>1.2.13</logback.version>
<spring-framework.version>5.3.39</spring-framework.version>
</properties>
<!-- 依赖声明 -->
<dependencyManagement>
<dependencies>
<!-- 覆盖SpringFramework的依赖配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud 微服务 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud Alibaba 微服务 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot 依赖配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 覆盖logback的依赖配置-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- 覆盖tomcat的依赖配置-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>${tomcat.version}</version>
</dependency>
<!-- FastDFS 分布式文件系统 -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>${tobato.version}</version>
</dependency>
<!-- Springdoc webmvc 依赖配置 -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc.version}</version>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>pro.fessional</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version>
</dependency>
<!-- io常用工具类 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version>
</dependency>
<!-- excel工具 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<!-- 代码生成使用模板 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version>
</dependency>
<!-- JSON 解析器和生成器 -->
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version>
</dependency>
<!-- JWT -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>${jjwt.version}</version>
</dependency>
<!-- 线程传递值 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>${transmittable-thread-local.version}</version>
</dependency>
<!-- 核心模块 -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-core</artifactId>
<version>${.version}</version>
</dependency>
<!-- 接口模块 -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-swagger</artifactId>
<version>${.version}</version>
</dependency>
<!-- 安全模块 -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-security</artifactId>
<version>${.version}</version>
</dependency>
<!-- 权限范围 -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-datascope</artifactId>
<version>${.version}</version>
</dependency>
<!-- 多数据源 -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-datasource</artifactId>
<version>${.version}</version>
</dependency>
<!-- 分布式事务 -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-seata</artifactId>
<version>${.version}</version>
</dependency>
<!-- 日志记录 -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-log</artifactId>
<version>${.version}</version>
</dependency>
<!-- 缓存服务 -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-redis</artifactId>
<version>${.version}</version>
</dependency>
<!-- 系统接口 -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-api-system</artifactId>
<version>${.version}</version>
</dependency>
<!-- map转换 -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<!-- <dependency>-->
<!-- <groupId>cn.hutool</groupId>-->
<!-- <artifactId>hutool-all</artifactId>-->
<!-- <version>${hutool.version}</version>-->
<!-- </dependency>-->
</dependencies>
</dependencyManagement>
<modules>
<module>auth</module>
<module>gateway</module>
<module>modules</module>
<module>api</module>
<module>common</module>
</modules>
<packaging>pom</packaging>
<dependencies>
<!-- bootstrap 启动器 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<annotationProcessorPaths>
<!-- Lombok 处理器 -->
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</path>
<!-- MapStruct 处理器 -->
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.5.5.Final</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project>
2、子pom
<?xml version="1.0" encoding="UTF-8"?>
<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">
<parent>
<artifactId>-modules</artifactId>
<groupId>com.wkl</groupId>
<version>3.6.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>business</artifactId>
<description>
modules-bus业务模块
</description>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- RuoYi Common DataSource -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-datasource</artifactId>
</dependency>
<!-- RuoYi Common DataScope -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-datascope</artifactId>
</dependency>
<!-- RuoYi Common Log -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-log</artifactId>
</dependency>
<!-- RuoYi Common Swagger -->
<dependency>
<groupId>com.wkl</groupId>
<artifactId>-common-swagger</artifactId>
</dependency>
<dependency>
<groupId>co.elastic.clients</groupId>
<artifactId>elasticsearch-java</artifactId>
<version>8.15.5</version>
<exclusions>
<exclusion>
<artifactId>elasticsearch-rest-client</artifactId>
<groupId>org.elasticsearch.client</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-client</artifactId>
<version>8.15.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.17.0</version>
</dependency>
<dependency>
<groupId>jakarta.json</groupId>
<artifactId>jakarta.json-api</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- starter-test:junit + spring-test + mockito -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>