跳到主要内容【Java】Gradle 多模块项目实战:Spring Boot 微服务搭建全流程 | 极客日志Javajava
【Java】Gradle 多模块项目实战:Spring Boot 微服务搭建全流程
本文介绍了基于 Gradle 构建 Spring Boot 微服务多模块项目的完整流程。内容涵盖开发环境配置、父子工程目录结构设计、Gradle 构建脚本(build.gradle)、设置脚本(settings.gradle)及 Wrapper 配置。详细展示了如何统一公共配置、管理依赖版本以及编写子模块的具体代码和配置文件。通过购物服务和外卖服务的示例,演示了如何启动多个微服务实例,并提供了完整的代码片段供参考。
FlinkHero0 浏览 Gradle 于 2007 年首次发布,并于 2011 年被 Google 选为 Android 官方构建工具。相较于 XML,其采用 Groovy 语言实现了更简洁的语法,配合增量构建和缓存机制,显著提升了开发与发布阶段的运行效率。
随着云原生和微服务架构的普及,系统通常由多个模块组成,因此掌握这一构建工具尤为重要。本文提供的多模块 Gradle 项目搭建方案,既适用于新建项目,也能支持从 Maven 迁移的场景,帮助开发者快速落地使用。
开发环境
- macOS For Apple Silicon 26.0.1
- IntelliJ IDEA
开发流程
- 创建父子工程目录
父目录为 multi-gradle,两个子目录,一个为购物服务 (shop-service),一个为外卖服务 (takeout-service)。
- 编写父工程构建脚本 (build.gradle)
脚本分为三部分:
- Gradle 构建自身依赖(使用 spring-boot-gradle-plugin)。
- 所有工程的公共配置(包括组名和版本号)。
- 子工程的独立配置(包括 Java 版本、插件和依赖管理)。
- 编写父工程设置脚本 (settings.gradle)
设置了两个子工程,分别是购物和外卖,且子工程名称与子项目目录名完全一致。
- 编写购物服务子工程构建脚本 (shop-service/build.gradle)
添加了 spring-boot-starter-webmvc 等依赖。
- 编写购物服务子工程应用代码 (ShopServiceApplication.java)
编写一个 Spring Boot 启动主方法和一个可响应 hello 方法。
- 同理编写外卖服务子工程的构建脚本和应用代码 (TakeoutServiceApplication.java)
参考上述步骤,根据不同的业务需求编写。
- 编写购物和外卖的应用配置并启动服务
购物服务配置端口号为 8081,应用名为 shop-service。
外卖服务配置端口号为 8080,应用名为 takeout-service。
同时启动两个服务。
配置 Gradle Wrapper。
由于从 Gradle 官网下载较慢,此处通过阿里巴巴开源镜像站加速下载,后续的组件和依赖中均使用了阿里巴巴开源镜像站用于加速,做 gradle build 时即会开始下载。
配置与代码
工程目录结构
multi-gradle/
├── build.gradle
├── settings.gradle
├── gradle.properties
├── gradlew
├── gradlew.bat
├── 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
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
// 注册所有微服务子项目,名称与子项目目录名完全一致
include 'takeout-service', 'shop-service'
build.gradle
// 根项目 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
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.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class ShopServiceApplication {
public ShopServiceApplication() {}
private static final Logger log = LoggerFactory.getLogger(ShopServiceApplication.class);
public static void main(String[] args) {
SpringApplication.run(ShopServiceApplication.class, args);
}
@GetMapping("hello")
public String hello() {
log.info("hello");
return "hello";
}
}
shop-service/src/main/resources/application.yml
spring:
application:
name: shop-service
datasource:
url: jdbc:h2:mem:${spring.application.name}
server:
port: 8081
takeout-service/build.gradle
// 子项目 takeout-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
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.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@SpringBootApplication
public class TakeoutServiceApplication {
public TakeoutServiceApplication() {}
private static final Logger log = LoggerFactory.getLogger(TakeoutServiceApplication.class);
public static void main(String[] args) {
SpringApplication.run(TakeoutServiceApplication.class, args);
}
@GetMapping("hello")
public String hello() {
log.info("hello");
return "hello";
}
}
takeout-service/src/main/resources/application.yml
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.
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online