Java 单体仓库:代码组织实战指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么Java项目要采用单体仓库?

随着Java应用程序日益复杂,团队常常面临一个困境:将所有代码存储在一个仓库(单体仓库)中,还是将其拆分为多个微服务仓库(多仓库)。实践表明,对于拥有共享业务逻辑、库和配置的项目,单体仓库尤其有效。在Java中,它允许集中管理依赖项、版本和构建,简化了重构和集成。

在本文中,我们将详细解析如何在实际中组织Java单体仓库中的代码:从文件夹结构到CI/CD设置。你将学会如何避免常见错误并加速开发。



1. Java单体仓库的结构

单体仓库的关键原则是模块化。在Java中,这是通过多模块项目实现的。每个模块负责自己的领域:共享库、服务、工具。

典型结构示例:

my-java-monorepo/├── build.gradle          # 根构建文件├── settings.gradle       # 包含所有模块├── gradle.properties     # 共享依赖版本├── common-lib/           # 共享库(DTO、工具类)│   ├── build.gradle│   └── src/├── service-auth/         # 认证服务│   ├── build.gradle│   └── src/├── service-payment/      # 支付服务│   ├── build.gradle│   └── src/└── integration-tests/    # 集成测试    ├── build.gradle    └── src/

为了管理版本,将共享依赖项移到根build.gradle或pom.xml(对于Maven)中会很方便。在Gradle中,这通过subprojects块实现:

subprojects {    apply plugin: 'java'    group = 'com.pythonlib'    version = '1.0.0'

repositories { mavenCentral() }

dependencies { testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0' }}

这种结构使得无需复制配置即可轻松添加新服务,并确保所有模块使用相同的库版本。



2. 依赖项与版本管理

单体仓库的主要问题之一是版本冲突。在Java中,使用BOM(物料清单)或集中式依赖描述来解决这个问题。让我们看一个使用java-platform的Gradle示例。

让我们创建一个定义所有外部依赖项的platform模块:

// platform/build.gradleplugins {    id 'java-platform'}

javaPlatform { allowDependencies()}

dependencies { constraints { api 'com.fasterxml.jackson.core:jackson-databind:2.15.2' api 'org.springframework.boot:spring-boot-starter-web:3.1.5' api 'org.slf4j:slf4j-api:2.0.9' }}

现在,在每个服务中,你可以简单地引用该平台:

// service-auth/build.gradledependencies {    implementation platform(project(':platform'))    implementation 'com.fasterxml.jackson.core:jackson-databind'    implementation 'org.springframework.boot:spring-boot-starter-web'}

这确保了所有模块使用相同的版本。当platform中的版本更新时,更改会自动应用到所有服务。

提示: 对于Maven,在根pom.xml中使用<dependencyManagement>。它的工作方式类似。



3. 单体仓库的CI/CD

在单体仓库中组织持续集成需要特殊方法。你不能在每次提交时都构建所有模块——这会拖慢流水线。最优的解决方案是基于更改的增量构建。

使用paths的GitHub Actions示例:

name: Java CIon:                

博客

书籍推荐