Aller au contenu principal

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:

SectionDescription
<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:

CoucheRôleAnnotations
ControllerGestion des requêtes HTTP@RestController, @Controller
ServiceLogique métier@Service
RepositoryAccès aux données@Repository, interface JPA
ModelRepré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:

FormatAvantagesInconvénients
propertiesSimple, familierRépétitif pour structures complexes
ymlLisible, hiérarchiqueSensible à 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:

TypeSuffixeExemple
ContrôleurControllerUserController
ServiceServiceUserService
RepositoryRepositoryUserRepository
EntityAucunUser, Product
DTODTOUserDTO, CreateUserDTO
ExceptionExceptionResourceNotFoundException
ConfigurationConfigSecurityConfig

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:

  1. Créez un projet avec Spring Initializr (Spring Web uniquement)
  2. Importez-le dans VS Code
  3. Identifiez:
    • Le fichier pom.xml
    • La classe principale
    • Le fichier application.properties
    • Le répertoire des tests
  4. Dessinez l'arborescence sur papier

Exercice 2: Créer une Structure de Packages​

Objectif: Organiser le code en couches

Instructions:

  1. Dans le projet précédent, créez la structure:
    com.example.demo/
    ├── controller/
    ├── service/
    ├── repository/
    └── model/
  2. Créez des classes vides dans chaque package
  3. Vérifiez la compilation

Exercice 3: Configurer des Profiles​

Objectif: Créer des configurations par environnement

Instructions:

  1. Créez application-dev.properties:
    server.port=8080
    logging.level.root=DEBUG
  2. Créez application-prod.properties:
    server.port=80
    logging.level.root=WARN
  3. Testez l'activation de chaque profile

Questions de Révision​

  1. Quel fichier contient les dépendances Maven?

  2. À quoi sert le répertoire target/?

  3. Quelle est la différence entre static/ et templates/?

  4. Que contient l'annotation @SpringBootApplication?

  5. Comment nommer un fichier de configuration pour l'environnement de développement?

  6. Quelle est la convention de nommage pour les classes de contrôleur?

  7. Où placez-vous les fichiers CSS et JavaScript?

  8. Quelle est la différence entre application.properties et application.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

Retour au Module 2