Monorepo avec Java : organisation du code en pratique

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Monorepo avec Java : organisation du code en pratique

\n

Dans le développement Java moderne, la question du choix entre un monorepo (monorepository) et plusieurs dépôts distincts se pose de plus en plus fréquemment. Un monorepo est une approche où tout le code du projet (plusieurs services, bibliothèques, configurations) est stocké dans un seul dépôt Git. Dans cet article, nous allons voir comment organiser un monorepo avec Java en pratique : de la structure des dossiers à la configuration de la construction et du CI/CD. Vous obtiendrez des exemples de code prêts à l'emploi et des recommandations pour éviter les erreurs typiques.

\n\n

Pourquoi un monorepo pour Java ?

\n

Le monorepo est particulièrement utile pour les projets Java où de nombreux modules dépendent les uns des autres. Les principaux avantages :

\n
    \n
  • Version unique des dépendances — tous les modules utilisent une seule version des bibliothèques, ce qui élimine les conflits.
  • \n
  • Refactorisation simplifiée — la modification d'une API dans un module est immédiatement visible dans tous les modules dépendants.
  • \n
  • Configuration de construction commune — Gradle ou Maven sont configurés une fois pour tous les modules.
  • \n
  • Intégrité du CI/CD — un seul pipeline pour tous les services, plus facile à suivre les modifications.
  • \n
\n

Cependant, le monorepo exige de la discipline : sans une structure claire, il se transforme en chaos. Examinons l'organisation correcte.

\n\n

Structure d'un monorepo pour un projet Java

\n

Structure recommandée pour un monorepo avec Java (exemple avec Gradle) :

\n
my-monorepo/\n├── build.gradle.kts          # fichier de construction racine\n├── settings.gradle.kts       # inclut tous les modules\n├── gradle.properties         # propriétés communes\n├── libs/                     # bibliothèques communes\n│   ├── common-utils/\n│   │   ├── build.gradle.kts\n│   │   └── src/\n│   └── logging/\n│       ├── build.gradle.kts\n│       └── src/\n├── services/                 # microservices\n│   ├── user-service/\n│   │   ├── build.gradle.kts\n│   │   └── src/\n│   └── payment-service/\n│       ├── build.gradle.kts\n│       └── src/\n├── config/                   # configurations (ex : checkstyle, spotbugs)\n│   └── checkstyle.xml\n└── docker/                   # Dockerfile pour chaque service\n    ├── user-service.Dockerfile\n    └── payment-service.Dockerfile\n
\n

Principes clés :

\n
    \n
  • Les modules sont divisés en libs (bibliothèques) et services (applications exécutables).
  • \n
  • Le fichier racine build.gradle.kts définit les plugins et versions communs.
  • \n
  • Le fichier settings.gradle.kts inclut tous les sous-projets.
  • \n
\n

Exemple de settings.gradle.kts :

\n
rootProject.name = "my-monorepo"\n\ninclude(\n    "libs:common-utils",\n    "libs:logging",\n    "services:user-service",\n    "services:payment-service"\n)\n
\n\n

Configuration des dépendances entre modules

\n

La tâche principale d'un monorepo est de gérer les dépendances internes. Prenons l'exemple où user-service dépend de common-utils.

\n

Étape 1. Dans le fichier racine gradle.properties, déclarez les versions :

\n
# gradle.properties\nkotlinVersion=1.9.0\nspringBootVersion=3.2.0\ncommonUtilsVersion=1.0.0\n
\n

Étape 2. Dans le fichier racine build.gradle.kts, ajoutez les plugins et définissez les paramètres communs :

\n
plugins {\n    id("java-library") apply false\n    id("org.springframework.boot") version "3.2.0" apply false\n    id("io.spring.dependency-management") version "1.1.4" apply false\n}\n\nallprojects {\n    group = "com.example"\n    version = "1.0.0"\n\n    repositories {\n        mavenCentral()\n    }\n}\n\nsubprojects {\n    apply(plugin = "java-library")\n\n    java {\n        sourceCompatibility = JavaVersion.VERSION_17\n        targetCompatibility = JavaVersion.VERSION_17\n    }\n\n    dependencies {\n        implementation("org.slf4j:slf4j-api:2.0.9")\n        testImplementation("org.j                

Blogs

Book Recommendations