Spring Boot 多模块项目依赖管理:父工程与子工程的区别与最佳实践

在 Maven 多模块项目(尤其是 Spring Boot 微服务项目)中,父工程(parent pom)和子工程(module pom)的依赖配置是决定项目可维护性、包体积和版本统一的关键。本文详细说明两者的区别、作用以及推荐写法。

核心机制对比

Maven 通过两个标签控制父子依赖关系:

位置 作用 子工程是否需要写 <dependency> 子工程是否需要写版本号 是否自动引入 jar 包到子工程
父 pom <dependencyManagement> 统一版本管理(只声明版本,不引入包) 需要写 可以省略(推荐)
父 pom <dependencies> 自动引入依赖到所有子工程 不需要写 不需要写

实际配置示例

父工程 pom.xml(chat2excel-parent)

<?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.anmory</groupId>
    <artifactId>chat2excel-parent</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>pom</packaging>

    <modules>
        <module>common</module>
        <module>user-service</module>
        <module>order-service</module>
        <module>gateway</module>
    </modules>

    <properties>
        <java.version>17</java.version>
        <spring-boot.version>3.2.0</spring-boot.version>
    </properties>

    <!-- 统一版本管理(推荐所有公共依赖都放这里) -->
    <dependencyManagement>
        <dependencies>
            <!-- Spring Boot 依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <version>${spring-boot.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
                <version>${spring-boot.version}</version>
            </dependency>

            <!-- 数据库 -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-j</artifactId>
                <version>8.4.0</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>3.5.7</version>
            </dependency>

            <!-- 其他公共依赖 -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.30</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <!-- 所有子模块都必须引入的依赖(慎用,只放真正全局的) -->
    <dependencies>
        <!-- 示例:lombok 所有模块都需要 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.11.0</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

子工程 pom.xml(user-service 示例)

<?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>

    <parent>
        <groupId>com.anmory</groupId>
        <artifactId>chat2excel-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <artifactId>user-service</artifactId>

    <dependencies>
        <!-- 继承父工程版本,无需写 version -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
        </dependency>

        <!-- lombok 自动继承,无需声明 -->
        <!-- test 依赖也自动继承 -->

        <!-- user-service 独有依赖 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

        <dependency>
            <groupId>com.anmory</groupId>
            <artifactId>common</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

最佳实践建议

  1. 版本统一管理:所有第三方库版本、插件版本都放在父工程的 <dependencyManagement> 中。
  2. 全局必备依赖:lombok、test、logging 等真正所有模块都用的,放在父工程的 <dependencies>
  3. 模块特有依赖:只写在对应子模块的 pom 中(如 nacos、gateway 相关)。
  4. 避免过度使用 <dependencies>:否则会导致每个子模块都打包大量无用 jar。
  5. 覆盖版本:子工程需要不同版本时,可显式写 <version> 覆盖父工程声明。
  6. 父工程必须是 pom<packaging>pom</packaging>,否则子模块继承会失败。

通过合理使用 dependencyManagementdependencies,可以实现版本统一、jar 包不冗余、维护成本最低的依赖管理。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐