【Java】Gradle 多模块项目实战:Spring Boot 微服务搭建全流程

Gradle 于 2007 年首次发布,并于 2011 年被 Google 选为 Android 官方构建工具。相较于 XML,其采用 Groovy 语言实现了更简洁的语法,配合增量构建和缓存机制,显著提升了开发与发布阶段的运行效率。[研究数据表明,Gradle 在构建 Spring Boot 项目时速度优于 Maven](#研究数据表明,Gradle 在构建 Spring Boot 项目时速度优于 Maven)1

随着云原生和微服务架构的普及,系统通常由多个模块组成,因此掌握这一构建工具尤为重要。本文提供的多模块 Gradle 项目搭建方案,既适用于新建项目,也能支持从 Maven 迁移的场景,帮助开发者快速落地使用。

目录

开发环境

开发流程

  1. 创建父子工程目录
    父目录为multi-gradle,两个子目录,一个为购物服务,一个为外卖服务,购物服务目录为shop-service,外卖服务为takeout-service.
  2. 配置Gradle Wrapper,见gradle-wrapper.properties
    由于从 Gradle 官网下载较慢,此处通过阿里巴巴开源镜像站加速下载,后续的组件和依赖中均使用了阿里巴巴开源镜像站用于加速,做gradle build时即会开始下载
  3. 编写父工程构建脚本,见build.gradle
    脚本分为三部分:
    • Gradle 构建自身依赖(使用 spring-boot-gradle-plugin)。
    • 所有工程的公共配置(包括组名和版本号)。
    • 子工程的独立配置(包括 Java 版本、插件和依赖管理)。
  4. 编写父工程设置脚本,设置好子工程,见settings.gradle
    设置了两个子工程,分别是购物和外卖,且子工程名称与子项目目录名完全一致.
  5. 编写购物服务子工程构建脚本,见shop-service/build.gradle
    添加了spring-boot-starter-webmvc等依赖
  6. 编写购物服务子工程应用代码,见ShopServiceApplication.java
    编写一个spring boot启动主方法和一个可响应hello方法
  7. 同理编写外卖服务子工程的构建脚本和应用代码,见takeout-service/build.gradleTakeoutServiceAppliction.java
    参考第六步和第七步,根据不同的业务
  8. 运行gradle build
  9. 编写购物和外卖的应用配置并启动购物和外卖服务
    购物服务配置好端口号为8081,应用名为shop-service,见application.yml
    外卖服务配置好端口号为8080,应用名为takeout-service,见application.yml
    同时启动两个服务

运行效果

启动购物服务图

启动外卖服务图

配置与代码

工程目录结构

nix 复制代码
multi-gradle/
├── build.gradle                # 项目构建脚本(Groovy DSL)
├── settings.gradle             # 项目设置文件,定义包含的子模块
├── gradle.properties           # 项目级 Gradle 配置属性
├── gradlew                     # Gradle 包装器脚本(Unix/Linux)
├── gradlew.bat                 # Gradle 包装器脚本(Windows)
├── gradle/                     # 包装器相关文件
│   └── wrapper/
│       └── gradle-wrapper.properties
└── shop-service/                  # 子模块 购物
    ├── build.gradle            # 子模块构建脚本
    └── src/                    # 子模块源代码目录
        ├── main/
        │   └── com.example.ShopServiceApplication
        └── test/
└── takeout-service/                  # 子模块 外卖
    ├── build.gradle            # 子模块构建脚本
    └── src/                    # 子模块源代码目录
        ├── main/
        │   └── com.example.TakeoutServiceApplication
        └── test/

gradle-wrapper.properties

其中gradle组件使用了国内阿里云的镜像

properties 复制代码
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://mirrors.aliyun.com/gradle/distributions/v9.3.1/gradle-9.3.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

settings.gradle

groovy 复制代码
// 注册所有微服务子项目,名称与子项目目录名完全一致
include  'takeout-service','shop-service'

build.gradle

groovy 复制代码
// 根项目 build.gradle(Groovy DSL)
// ########## 核心1:buildscript 声明插件依赖(Gradle构建自身的依赖)##########
buildscript {
    // 插件仓库(必须配置,拉取Spring Boot插件)
    repositories {
        mavenLocal()
        // 第一步:优先从阿里云镜像拉取(速度快)
        maven { url = 'https://maven.aliyun.com/repository/public/' }
        maven { url = 'https://maven.aliyun.com/repository/gradle-plugin' }
        // 第二步:镜像未找到时,官方仓库兜底(可选)
        gradlePluginPortal()
        mavenCentral()
    }
    // 声明插件的Maven坐标(group:name:version)
    dependencies {
        classpath "org.springframework.boot:spring-boot-gradle-plugin:4.0.2"
    }
}

// ########## 全局公共配置 ##########
allprojects {
    group = 'com.example'
    version = '0.1.0'
    repositories {
        maven { url = 'https://maven.aliyun.com/repository/public/' }
        mavenLocal()
        mavenCentral()
    }
}
// ########## 核心2:subprojects 中统一应用插件(无id()方法,用apply plugin)##########
subprojects {
    // 应用核心插件+Spring Boot插件(无语法冲突)
    apply plugin: 'java'
    apply plugin: 'maven-publish'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    java {
        toolchain {
            languageVersion = JavaLanguageVersion.of(25) // 所有子模块统一使用 Java 25
        }
    }

    // 全局版本常量+公共依赖(与之前一致)
    dependencies {
        testImplementation 'org.springframework.boot:spring-boot-starter-test'
//         Gradle 9.x 需显式声明JUnit 5平台启动器
//        testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    }

    // Spring Cloud 版本统一(可选)
    dependencyManagement {
        imports {
            mavenBom "org.springframework.cloud:spring-cloud-dependencies:2025.1.0"
        }
    }
    // 核心配置:启用JUnit 5平台,让Gradle识别JUnit 5的@Test注解
    tasks.test {
        useJUnitPlatform() // 必须添加,否则Gradle无法扫描JUnit 5测试用例
    }
}

shop-service/build.gradle

复制代码
// 子项目 shop-service/build.gradle(Groovy DSL)
// 无需重复写repositories、group、version、公共依赖!
// 仅写当前微服务特有的依赖/配置

dependencies {
    // 自身业务特有依赖(如用户模块的持久层、服务层依赖)
    implementation 'org.springframework.boot:spring-boot-starter-webmvc'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    runtimeOnly("com.h2database:h2")
}

// 可选:覆盖全局配置(如需单独指定版本/插件)
// version = '1.0.1' // 覆盖根项目的version

ShopServiceApplication.java

java 复制代码
package com.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.service.annotation.GetExchange;
/// 购物服务
@RestController
@SpringBootApplication
public class ShopServiceApplication {
    /// 构造方法
    public ShopServiceApplication(){

    }

    private static final Logger log = LoggerFactory.getLogger(ShopServiceApplication.class);

    /**
     * 主方法
     * @param args  命令行参数
     */
    public static void main(String[] args) {
        SpringApplication.run(ShopServiceApplication.class, args);
    }

    /**
     * hello
     *
     * @return hello
     */
    @GetExchange("hello")
    public String hello() {
        log.info("hello");
        return "hello";
    }
}

shop-service/src/main/resources/application.yml

yaml 复制代码
spring:
  application:
    name: shop-service
  datasource:
    url: jdbc:h2:mem:${spring.application.name}
server:
  port: 8081

takeout-service/build.gradle

groovy 复制代码
// 子项目 taskout-service/build.gradle(Groovy DSL)
// 无需重复写repositories、group、version、公共依赖!
// 仅写当前微服务特有的依赖/配置

dependencies {
    // 自身业务特有依赖(如用户模块的持久层、服务层依赖)
    implementation 'org.springframework.boot:spring-boot-starter-webmvc'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    runtimeOnly("com.h2database:h2")
}

// 可选:覆盖全局配置(如需单独指定版本/插件)
// version = '1.0.1' // 覆盖根项目的version

TakeoutServiceApplication.java

java 复制代码
package com.example;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.service.annotation.GetExchange;

/// 外卖服务
@RestController
@SpringBootApplication
public class TakeoutServiceApplication {
    /// 构造方法
    public TakeoutServiceApplication() {

    }

    private static final Logger log = LoggerFactory.getLogger(TakeoutServiceApplication.class);

    /**
     * 主方法
     * @param args  命令行参数
     */
    public static void main(String[] args) {
        SpringApplication.run(TakeoutServiceApplication.class, args);
    }

    /**
     * hello
     *
     * @return hello
     */
    @GetExchange("hello")
    public String hello() {
        log.info("hello");
        return "hello";
    }
}

takeout-service/src/main/resources/application.yml

yaml 复制代码
spring:
  application:
    name: takeout-service
  datasource:
    url: jdbc:h2:mem:${spring.application.name}

引用

1\]崔娟,张生月,章恒.Maven与Gradle构建工具对比分析\[J\].科技创新与应用,2025,15(21):93-96.DOI:10.19981/j.CN23-1581/G3.2025.21.021.

相关推荐
追随者永远是胜利者16 分钟前
(LeetCode-Hot100)169. 多数元素
java·算法·leetcode·go
蜜獾云27 分钟前
JAVA面试题速记-第1期-java基础
java·开发语言
百锦再44 分钟前
Java中的反射机制详解:从原理到实践的全面剖析
java·开发语言·jvm·spring boot·struts·spring cloud·kafka
没有bug.的程序员1 小时前
Gradle 构建优化深度探秘:从 Java 核心到底层 Android 物理性能压榨实战指南
android·java·开发语言·分布式·缓存·gradle
tianyagukechat1 小时前
rockylinux9.5 配置IP
java·网络·tcp/ip
程序员Sonder2 小时前
黑马java----正则表达式(一文弄懂)
java·正则表达式·新人首发
doris82042 小时前
Python 正则表达式 re.findall()
java·python·正则表达式
Anastasiozzzz2 小时前
阿亮随手记:动态条件生成Bean
java·前端·数据库
树码小子3 小时前
图书管理系统(5)强制登陆(后端实现)
spring boot·mybatis·图书管理系统
丹牛Daniel3 小时前
Java解决HV000183: Unable to initialize ‘javax.el.ExpressionFactory‘
java·开发语言·spring boot·tomcat·intellij-idea·个人开发