Chapitre 2: Structure d'un Projet Spring Boot
Introduction
Un projet Spring Boot suit une structure standardisée basée sur les conventions Maven. Cette organisation facilite la navigation dans le code et permet aux développeurs de trouver rapidement les fichiers nécessaires.
Objectifs du Chapitre
À la fin de ce chapitre, vous serez capable de:
- Comprendre l'organisation des répertoires d'un projet Spring Boot
- Identifier le rôle de chaque fichier important
- Organiser votre code selon les bonnes pratiques
- Naviguer efficacement dans un projet Spring Boot
Vue d'Ensemble de la Structure
Arborescence Complète
greeting-app/
├── .mvn/ # Maven Wrapper
│ └── wrapper/
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── src/
│ ├── main/
│ │ ├── java/ # Code source Java
│ │ │ └── com/example/greeting/
│ │ │ └── GreetingApplication.java
│ │ └── resources/ # Ressources de l'application
│ │ ├── static/ # Fichiers statiques (CSS, JS, images)
│ │ ├── templates/ # Templates (Thymeleaf, Freemarker)
│ │ ├── application.properties # Configuration principale
│ │ └── application.yml # Configuration YAML (alternative)
│ └── test/
│ ├── java/ # Tests unitaires et d'intégration
│ │ └── com/example/greeting/
│ │ └── GreetingApplicationTests.java
│ └── resources/ # Ressources de test
│ └── application-test.properties
├── target/ # Fichiers compilés (généré)
├── .gitignore # Fichiers à ignorer par Git
├── mvnw # Maven wrapper (Unix/macOS)
├── mvnw.cmd # Maven wrapper (Windows)
├── pom.xml # Configuration Maven
├── HELP.md # Documentation générée
└── README.md # Documentation du projet
Répertoire Racine
1. Fichier pom.xml
Rôle: Fichier de configuration Maven (Project Object Model)
Contenu principal:
<?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
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- Parent Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/>
</parent>
<!-- Identifiants du projet -->
<groupId>com.example</groupId>
<artifactId>greeting</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>greeting</name>
<description>Application de salutation</description>
<!-- Propriétés -->
<properties>
<java.version>17</java.version>
</properties>
<!-- Dépendances -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Plugin de build -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Sections importantes:
| Section | Description |
|---|---|
<parent> | Hérite de la configuration Spring Boot |
<groupId>, <artifactId>, <version> | Coordonnées Maven du projet |
<properties> | Configuration globale (version Java, encodage, etc.) |
<dependencies> | Liste des dépendances du projet |
<build> | Configuration du processus de build |
2. Maven Wrapper (mvnw, mvnw.cmd)
Rôle: Permet d'exécuter Maven sans l'installer globalement
Avantages:
- Version Maven garantie pour tous les développeurs
- Pas besoin d'installer Maven manuellement
- Scripts inclus dans le projet
Utilisation:
Linux/macOS:
./mvnw clean install
./mvnw spring-boot:run
Windows:
mvnw.cmd clean install
mvnw.cmd spring-boot:run
3. Fichier .gitignore
Rôle: Liste des fichiers à ne pas versionner avec Git
Contenu typique:
# Fichiers compilés
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
# IDE
.idea/
*.iml
.vscode/
.classpath
.project
.settings/
# Système
.DS_Store
Thumbs.db
# Logs
*.log
# Fichiers temporaires
*.tmp
*.bak
Répertoire src/main/java
Structure des Packages
Convention: Organiser le code en couches fonctionnelles
src/main/java/com/example/greeting/
├── GreetingApplication.java # Classe principale
├── controller/ # Contrôleurs REST/MVC
│ ├── GreetingController.java
│ └── UserController.java
├── service/ # Logique métier
│ ├── GreetingService.java
│ └── UserService.java
├── repository/ # Accès aux données
│ ├── UserRepository.java
│ └── ProductRepository.java
├── model/ # Entités et DTOs
│ ├── entity/
│ │ ├── User.java
│ │ └── Product.java
│ └── dto/
│ ├── UserDTO.java
│ └── ProductDTO.java
├── config/ # Configuration Spring
│ ├── SecurityConfig.java
│ └── DatabaseConfig.java
├── exception/ # Gestion des erreurs
│ ├── ResourceNotFoundException.java
│ └── GlobalExceptionHandler.java
└── util/ # Classes utilitaires
└── DateUtil.java
Architecture en Couches
Responsabilités de chaque couche:
| Couche | Rôle | Annotations |
|---|---|---|
| Controller | Gestion des requêtes HTTP | @RestController, @Controller |
| Service | Logique métier | @Service |
| Repository | Accès aux données | @Repository, interface JPA |
| Model | Représentation des données | @Entity, POJO |
Classe Principale: GreetingApplication.java
Contenu:
package com.example.greeting;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GreetingApplication {
public static void main(String[] args) {
SpringApplication.run(GreetingApplication.class, args);
}
}
Annotation @SpringBootApplication:
Cette annotation est un raccourci qui combine trois annotations:
@SpringBootApplication
=
@SpringBootConfiguration // Configuration Spring
+ @EnableAutoConfiguration // Auto-configuration
+ @ComponentScan // Scan des composants
Rôle de chaque annotation:
Répertoire src/main/resources
Vue d'Ensemble
src/main/resources/
├── static/ # Fichiers statiques
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ └── script.js
│ └── images/
│ └── logo.png
├── templates/ # Templates (Thymeleaf)
│ ├── index.html
│ └── user.html
├── application.properties # Configuration principale
├── application-dev.properties # Configuration développement
├── application-prod.properties # Configuration production
├── application.yml # Configuration YAML (alternative)
├── banner.txt # Banner personnalisé au démarrage
└── data.sql # Script SQL d'initialisation
1. Répertoire static/
Rôle: Contient les fichiers statiques servis directement
Types de fichiers:
- CSS (feuilles de style)
- JavaScript (scripts côté client)
- Images (PNG, JPG, SVG)
- Fonts (polices personnalisées)
Accès:
http://localhost:8080/css/style.css
http://localhost:8080/js/script.js
http://localhost:8080/images/logo.png
Structure recommandée:
static/
├── css/
├── js/
├── images/
├── fonts/
└── favicon.ico
2. Répertoire templates/
Rôle: Contient les templates de vues (si vous utilisez un moteur de templates)
Moteurs de templates supportés:
- Thymeleaf (recommandé)
- Freemarker
- Mustache
- Groovy Templates
Exemple Thymeleaf:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Greeting</title>
</head>
<body>
<h1 th:text="${message}">Default message</h1>
</body>
</html>
3. Fichier application.properties
Rôle: Configuration principale de l'application
Format: clé=valeur
Exemples de configurations:
# Port du serveur
server.port=8080
# Nom de l'application
spring.application.name=greeting-app
# Configuration de la base de données
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=postgres
spring.datasource.password=secret
# JPA/Hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# Logs
logging.level.root=INFO
logging.level.com.example=DEBUG
# Format des dates
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=America/Montreal
4. Fichier application.yml (Alternative)
Rôle: Même que application.properties mais en format YAML
Format: Hiérarchique avec indentation
Exemple équivalent:
server:
port: 8080
spring:
application:
name: greeting-app
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: postgres
password: secret
jpa:
hibernate:
ddl-auto: update
show-sql: true
logging:
level:
root: INFO
com.example: DEBUG
Comparaison:
| Format | Avantages | Inconvénients |
|---|---|---|
| properties | Simple, familier | Répétitif pour structures complexes |
| yml | Lisible, hiérarchique | Sensible à l'indentation |
5. Profiles de Configuration
Concept: Configurations différentes selon l'environnement
Fichiers de profiles:
application.properties # Configuration par défaut
application-dev.properties # Développement
application-test.properties # Tests
application-prod.properties # Production
Activation d'un profile:
Via application.properties:
spring.profiles.active=dev
Via ligne de commande:
java -jar app.jar --spring.profiles.active=prod
Via variable d'environnement:
export SPRING_PROFILES_ACTIVE=prod
Exemple de configuration par environnement:
application-dev.properties:
server.port=8080
spring.datasource.url=jdbc:h2:mem:testdb
logging.level.root=DEBUG
application-prod.properties:
server.port=80
spring.datasource.url=jdbc:postgresql://prod-server:5432/mydb
logging.level.root=WARN
Répertoire src/test/java
Structure des Tests
src/test/java/com/example/greeting/
├── GreetingApplicationTests.java # Test de démarrage
├── controller/
│ └── GreetingControllerTest.java # Tests du contrôleur
├── service/
│ └── GreetingServiceTest.java # Tests du service
└── repository/
└── UserRepositoryTest.java # Tests du repository
Test de Démarrage par Défaut
package com.example.greeting;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class GreetingApplicationTests {
@Test
void contextLoads() {
// Vérifie que le contexte Spring se charge correctement
}
}
Rôle: Vérifier que l'application démarre sans erreur
Répertoire target/
Rôle: Contient les fichiers compilés et le JAR final
Généré par: Maven lors du build
Contenu:
target/
├── classes/ # Classes compilées (.class)
├── test-classes/ # Tests compilés
├── generated-sources/ # Sources générées
├── maven-status/ # Statut Maven
└── greeting-0.0.1-SNAPSHOT.jar # JAR exécutable final
Important: Ce répertoire est ignoré par Git (dans .gitignore)
Nettoyage:
mvn clean
Organisation par Fonctionnalité vs par Couche
Approche 1: Par Couche (Recommandée pour petits projets)
com.example.greeting/
├── controller/
│ ├── UserController.java
│ └── ProductController.java
├── service/
│ ├── UserService.java
│ └── ProductService.java
├── repository/
│ ├── UserRepository.java
│ └── ProductRepository.java
└── model/
├── User.java
└── Product.java
Avantages:
- Simple et clair
- Facile à comprendre pour les débutants
- Standard Spring Boot
Inconvénients:
- Difficile à scaler pour de gros projets
- Couplage entre fonctionnalités
Approche 2: Par Fonctionnalité (Recommandée pour gros projets)
com.example.greeting/
├── user/
│ ├── UserController.java
│ ├── UserService.java
│ ├── UserRepository.java
│ └── User.java
├── product/
│ ├── ProductController.java
│ ├── ProductService.java
│ ├── ProductRepository.java
│ └── Product.java
└── order/
├── OrderController.java
├── OrderService.java
├── OrderRepository.java
└── Order.java
Avantages:
- Haute cohésion
- Faible couplage
- Facilite le passage à une architecture microservices
Inconvénients:
- Moins standard
- Peut être déroutant au début
Conventions de Nommage
Packages
Convention: Tout en minuscules, mots séparés par des points
com.example.greeting // ✅ Bon
com.example.greeting.service // ✅ Bon
com.Example.Greeting // ❌ Mauvais (majuscules)
com.example.greeting_service // ❌ Mauvais (underscore)
Classes
Convention: PascalCase (première lettre de chaque mot en majuscule)
UserController // ✅ Bon
GreetingService // ✅ Bon
userController // ❌ Mauvais (commence par minuscule)
user_controller // ❌ Mauvais (underscore)
Suffixes recommandés:
| Type | Suffixe | Exemple |
|---|---|---|
| Contrôleur | Controller | UserController |
| Service | Service | UserService |
| Repository | Repository | UserRepository |
| Entity | Aucun | User, Product |
| DTO | DTO | UserDTO, CreateUserDTO |
| Exception | Exception | ResourceNotFoundException |
| Configuration | Config | SecurityConfig |
Méthodes
Convention: camelCase (première lettre minuscule)
getUserById() // ✅ Bon
findAllUsers() // ✅ Bon
GetUserById() // ❌ Mauvais (commence par majuscule)
get_user_by_id() // ❌ Mauvais (underscore)
Variables et Attributs
Convention: camelCase
String userName; // ✅ Bon
int userId; // ✅ Bon
String UserName; // ❌ Mauvais (commence par majuscule)
String user_name; // ❌ Mauvais (underscore)
Constantes
Convention: SCREAMING_SNAKE_CASE (tout en majuscules, underscores)
public static final int MAX_USERS = 100; // ✅ Bon
public static final String API_BASE_URL = "/api/v1"; // ✅ Bon
public static final int maxUsers = 100; // ❌ Mauvais (camelCase)
Exercices Pratiques
Exercice 1: Explorer la Structure
Objectif: Se familiariser avec la structure d'un projet
Instructions:
- Créez un projet avec Spring Initializr (Spring Web uniquement)
- Importez-le dans VS Code
- Identifiez:
- Le fichier pom.xml
- La classe principale
- Le fichier application.properties
- Le répertoire des tests
- Dessinez l'arborescence sur papier
Exercice 2: Créer une Structure de Packages
Objectif: Organiser le code en couches
Instructions:
- Dans le projet précédent, créez la structure:
com.example.demo/
├── controller/
├── service/
├── repository/
└── model/ - Créez des classes vides dans chaque package
- Vérifiez la compilation
Exercice 3: Configurer des Profiles
Objectif: Créer des configurations par environnement
Instructions:
- Créez
application-dev.properties:server.port=8080
logging.level.root=DEBUG - Créez
application-prod.properties:server.port=80
logging.level.root=WARN - Testez l'activation de chaque profile
Questions de Révision
-
Quel fichier contient les dépendances Maven?
-
À quoi sert le répertoire
target/? -
Quelle est la différence entre
static/ettemplates/? -
Que contient l'annotation
@SpringBootApplication? -
Comment nommer un fichier de configuration pour l'environnement de développement?
-
Quelle est la convention de nommage pour les classes de contrôleur?
-
Où placez-vous les fichiers CSS et JavaScript?
-
Quelle est la différence entre
application.propertiesetapplication.yml?
Résumé du Chapitre
Points Clés
- La structure Spring Boot suit les conventions Maven
- Le code source est dans
src/main/java - Les ressources sont dans
src/main/resources - Organisation en couches: Controller → Service → Repository
- Les tests sont dans
src/test/java - Les fichiers de configuration utilisent des profiles
Bonnes Pratiques
- Respecter les conventions de nommage Java
- Organiser le code en packages logiques
- Séparer les configurations par environnement
- Utiliser des suffixes descriptifs pour les classes
- Commenter le code complexe
- Maintenir une structure claire et cohérente
Prochaines Étapes
Dans le chapitre suivant, nous approfondirons:
Chapitre 3: Configuration avec application.properties
- Propriétés Spring Boot disponibles
- Configuration de la base de données
- Configuration des logs
- Propriétés personnalisées