■
SPRING BOOT
Cours Complet en Java
Du projet de base à l'API REST sécurisée en production
Spring Boot 3.x • Java 17+ • Maven • JPA • Security • Docker
Mr Roly — May 2026
COURS COMPLET SPRING BOOT Java • Spring Boot 3.x
TABLE DES MATIÈRES
Chapitre 1 — Introduction à Spring Boot
■ Qu'est-ce que Spring Boot ?
■ Spring vs Spring Boot
■ Architecture et auto-configuration
■ Installation & prérequis
Chapitre 2 — Créer son premier projet
■ Spring Initializr
■ Structure du projet Maven
■ Le fichier [Link]
■ Premier démarrage de l'application
Chapitre 3 — Injection de dépendances & IoC
■ Conteneur IoC
■ Annotations @Component, @Service, @Repository
■ @Autowired et injection par constructeur
■ Beans et cycle de vie
Chapitre 4 — Création d'une API REST
■ @RestController & @RequestMapping
■ GET, POST, PUT, DELETE
■ Gestion des paramètres et du corps
■ Codes HTTP & ResponseEntity
Chapitre 5 — Persistance avec Spring Data JPA
■ ORM et Hibernate
■ Entités et annotations JPA
■ JpaRepository & requêtes
■ Relations entre entités
Chapitre 6 — Validation & Gestion des erreurs
■ Bean Validation (@Valid, @NotNull…)
■ @ExceptionHandler & @ControllerAdvice
■ Réponses d'erreur standardisées
Chapitre 7 — Spring Security & JWT
■ Principes de base de Spring Security
■ Authentification et autorisation
■ Implémentation JWT
■ Sécurisation des endpoints
Chapitre 8 — Tests avec Spring Boot
Spring Boot — Cours Complet | 2026 Page 2
■ @SpringBootTest & @WebMvcTest
■ Mockito et mocking
■ Tests de repository avec H2
Chapitre 9 — Configuration avancée & Profils
■ Profils Spring (dev, prod)
■ Externalization de la configuration
■ @ConfigurationProperties
Chapitre 10 — Déploiement avec Docker
■ Dockerfile pour Spring Boot
■ Docker Compose avec PostgreSQL
■ Variables d'environnement
CHAPITRE 1
Introduction à Spring Boot
1.1 Qu'est-ce que Spring Boot ?
Spring Boot est un framework Java open-source développé par Pivotal (VMware) qui simplifie
radicalement la création d'applications Spring. Il adopte une approche « convention over
configuration » : au lieu de configurer manuellement chaque composant, Spring Boot applique des
configurations par défaut intelligentes qui couvrent la grande majorité des cas d'usage.
Ses objectifs principaux :
• Créer des applications Spring stand-alone exécutables avec un simple java -jar
• Embarquer un serveur HTTP (Tomcat, Jetty, Undertow) directement dans le JAR
• Fournir des dépendances « starter » pré-configurées
• Éliminer la configuration XML et le boilerplate code
• Exposer des métriques de production via Actuator
1.2 Spring vs Spring Boot
Critère Spring Framework Spring Boot
Configuration XML ou Java verbeux Auto-configuration
Serveur web Externe (WAR) Embarqué (JAR)
Démarrage Long (beaucoup de config) Rapide (starter)
Courbe d'apprentissageÉlevée Modérée
Flexibilité Maximale Bonne (overridable)
1.3 Architecture & Auto-configuration
Le cœur de Spring Boot repose sur le mécanisme d'auto-configuration. Lors du démarrage, Spring
Boot analyse le classpath, les beans existants et les propriétés définies pour décider automatiquement
quelles configurations appliquer.
■ L'annotation @SpringBootApplication combine @Configuration, @EnableAutoConfiguration et
@ComponentScan.
@SpringBootApplication
public class MonApplication {
public static void main(String[] args) {
[Link]([Link], args);
}
}
1.4 Installation & Prérequis
Environnement requis :
• Java Development Kit (JDK) 17 ou supérieur
• Maven 3.6+ ou Gradle 7+
• IDE : IntelliJ IDEA (recommandé), Eclipse STS, VS Code
• Optionnel : Docker, Postman
# Vérifier la version Java
java -version
# java version "17.0.x" ...
# Vérifier Maven
mvn -version
# Apache Maven 3.9.x
CHAPITRE 2
Créer son Premier Projet
2.1 Spring Initializr
[Link] est l'outil officiel pour générer un projet Spring Boot en quelques clics. Il suffit de choisir :
le gestionnaire de build (Maven/Gradle), le langage (Java/Kotlin/Groovy), la version de Spring Boot, et
les dépendances (starters) dont vous avez besoin.
■■ Utilisez toujours une version Spring Boot stable (LTS). Évitez les versions SNAPSHOT en production.
Dépendances courantes à sélectionner :
• Spring Web — pour créer des APIs REST
• Spring Data JPA — pour la persistance
• H2 Database — base de données en mémoire pour le dev
• Lombok — pour réduire le boilerplate (getters/setters)
• Spring Boot DevTools — rechargement automatique en dev
2.2 Structure du Projet Maven
mon-projet/
■■■ src/
■ ■■■ main/
■ ■ ■■■ java/com/exemple/monprojet/
■ ■ ■ ■■■ [Link] ← Classe principale
■ ■ ■ ■■■ controller/ ← Couche présentation
■ ■ ■ ■■■ service/ ← Logique métier
■ ■ ■ ■■■ repository/ ← Accès aux données
■ ■ ■ ■■■ model/ ← Entités JPA
■ ■ ■ ■■■ dto/ ← Data Transfer Objects
■ ■ ■■■ resources/
■ ■ ■■■ [Link] ← Configuration
■ ■ ■■■ static/ ← Fichiers statiques
■ ■■■ test/
■ ■■■ java/... ← Tests unitaires
■■■ [Link] ← Dépendances Maven
2.3 Le fichier [Link]
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="[Link]
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
<groupId>[Link]</groupId>
<artifactId>mon-projet</artifactId>
<version>1.0.0</version>
<properties>
<[Link]>17</[Link]>
</properties>
<dependencies>
<!-- Spring Web (REST) -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- Base de données H2 (dev) -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Tests -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
2.4 [Link]
# ■■ Serveur ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
[Link]=8080
[Link]-path=/api
# ■■ Base de données ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
[Link]=jdbc:h2:mem:devdb
[Link]-class-name=[Link]
[Link]=sa
[Link]=
# ■■ JPA / Hibernate ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
[Link]-auto=create-drop
[Link]-sql=true
[Link].format_sql=true
# ■■ Console H2 (dev seulement) ■■■■■■■■■■■■■■■■■■■■■■■
[Link]=true
[Link]=/h2-console
■ En production, utilisez [Link] avec [Link]-auto=validate ou none.
CHAPITRE 3
Injection de Dépendances & IoC
3.1 Le Conteneur IoC
L'Inversion of Control (IoC) est le principe central de Spring. Au lieu que vos objets créent eux-mêmes
leurs dépendances, c'est le conteneur Spring (ApplicationContext) qui les instancie et les injecte. Cela
favorise le couplage faible et la testabilité.
3.2 Annotations Stéréotypes
Spring utilise des annotations pour détecter automatiquement les classes à gérer :
Annotation Rôle Couche
@Component Bean générique géré par Spring Toutes
@Service Logique métier (alias @Component) Service
@Repository Accès aux données + traduction exceptions Repository
@Controller Contrôleur MVC (vues HTML) Présentation
@RestController @Controller + @ResponseBody REST API
@Configuration Classe de configuration Spring Config
3.3 Injection par constructeur (recommandée)
// ■■ Service ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
@Service
public class EtudiantService {
private final EtudiantRepository repository; // final => immuable
// Injection par constructeur (pas besoin de @Autowired en Java moderne)
public EtudiantService(EtudiantRepository repository) {
[Link] = repository;
}
public List<Etudiant> findAll() {
return [Link]();
}
}
// ■■ Avec Lombok (encore plus concis) ■■■■■■■■■■■■■■■■■
@Service
@RequiredArgsConstructor // génère le constructeur automatiquement
public class EtudiantService {
private final EtudiantRepository repository;
public List<Etudiant> findAll() {
return [Link]();
}
}
3.4 @Bean et configuration manuelle
@Configuration
public class AppConfig {
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
@Primary
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
[Link](new JavaTimeModule());
[Link](SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
return mapper;
}
}
CHAPITRE 4
Création d'une API REST
4.1 @RestController & @RequestMapping
Un REST Controller est une classe annotée @RestController qui expose des endpoints HTTP.
Chaque méthode est mappée à une URL et un verbe HTTP grâce aux annotations de mapping.
4.2 CRUD complet — Exemple Étudiant
@RestController
@RequestMapping("/etudiants")
@RequiredArgsConstructor
public class EtudiantController {
private final EtudiantService service;
// GET /etudiants — Lister tous les étudiants
@GetMapping
public ResponseEntity<List<EtudiantDTO>> findAll() {
return [Link]([Link]());
}
// GET /etudiants/{id} — Trouver par ID
@GetMapping("/{id}")
public ResponseEntity<EtudiantDTO> findById(@PathVariable Long id) {
return [Link](id)
.map(ResponseEntity::ok)
.orElse([Link]().build());
}
// POST /etudiants — Créer un étudiant
@PostMapping
public ResponseEntity<EtudiantDTO> create(
@Valid @RequestBody EtudiantDTO dto) {
EtudiantDTO created = [Link](dto);
URI location = [Link]("/etudiants/" + [Link]());
return [Link](location).body(created);
}
// PUT /etudiants/{id} — Mettre à jour
@PutMapping("/{id}")
public ResponseEntity<EtudiantDTO> update(
@PathVariable Long id,
@Valid @RequestBody EtudiantDTO dto) {
return [Link]([Link](id, dto));
}
// DELETE /etudiants/{id} — Supprimer
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
[Link](id);
return [Link]().build();
}
// GET /etudiants/search?nom=Dupont — Recherche par paramètre
@GetMapping("/search")
public ResponseEntity<List<EtudiantDTO>> search(
@RequestParam String nom) {
return [Link]([Link](nom));
}
}
4.3 Codes HTTP et ResponseEntity
Code Signification Utilisation
200 OK Succès GET, PUT réussis
201 Created Ressource créée POST réussi
204 No Content Succès sans corps DELETE réussi
400 Bad Request Requête invalide Validation échouée
401 Unauthorized Non authentifié Token manquant/invalide
403 Forbidden Accès refusé Droits insuffisants
404 Not Found Ressource absente ID inexistant
500 Internal Error Erreur serveur Exception non gérée
CHAPITRE 5
Persistance avec Spring Data JPA
5.1 Entité JPA
@Entity
@Table(name = "etudiants")
@Data // Lombok : getters, setters, equals, hashCode, toString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Etudiant {
@Id
@GeneratedValue(strategy = [Link])
private Long id;
@Column(nullable = false, length = 100)
private String nom;
@Column(nullable = false, unique = true)
private String email;
@Column(name = "date_naissance")
private LocalDate dateNaissance;
@Enumerated([Link])
private Niveau niveau; // LICENCE_1, LICENCE_2, MASTER_1 ...
@ManyToOne(fetch = [Link])
@JoinColumn(name = "filiere_id")
private Filiere filiere;
@CreationTimestamp
@Column(updatable = false)
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
}
5.2 Repository — JpaRepository
@Repository
public interface EtudiantRepository extends JpaRepository<Etudiant, Long> {
// Spring Data génère automatiquement les requêtes à partir du nom de la méthode
List<Etudiant> findByNom(String nom);
List<Etudiant> findByNomContainingIgnoreCase(String nom);
Optional<Etudiant> findByEmail(String email);
List<Etudiant> findByNiveau(Niveau niveau);
boolean existsByEmail(String email);
// Requête JPQL personnalisée
@Query("SELECT e FROM Etudiant e WHERE [Link] = :filiere AND [Link] = :niveau")
List<Etudiant> findByFiliereAndNiveau(
@Param("filiere") String filiere,
@Param("niveau") Niveau niveau
);
// Requête SQL native
@Query(value = "SELECT * FROM etudiants ORDER BY RAND() LIMIT :n", nativeQuery = true)
List<Etudiant> findRandom(@Param("n") int n);
}
5.3 Relations entre entités
@OneToMany / @ManyToOne :
// Filière (côté One)
@Entity
public class Filiere {
@Id @GeneratedValue(strategy = [Link])
private Long id;
private String nom;
@OneToMany(mappedBy = "filiere", cascade = [Link], fetch = [Link])
private List<Etudiant> etudiants = new ArrayList<>();
}
// Etudiant (côté Many)
@Entity
public class Etudiant {
// ...
@ManyToOne(fetch = [Link])
@JoinColumn(name = "filiere_id")
private Filiere filiere;
}
■■ Évitez [Link] sur les collections — cela peut provoquer des N+1 queries et des problèmes
de performance.
CHAPITRE 6
Validation & Gestion des Erreurs
6.1 Bean Validation
// DTO avec contraintes de validation
public class EtudiantDTO {
private Long id;
@NotBlank(message = "Le nom est obligatoire")
@Size(min = 2, max = 100, message = "Le nom doit avoir entre 2 et 100 caractères")
private String nom;
@NotBlank(message = "L'email est obligatoire")
@Email(message = "Format d'email invalide")
private String email;
@NotNull(message = "La date de naissance est obligatoire")
@Past(message = "La date de naissance doit être dans le passé")
private LocalDate dateNaissance;
@NotNull
@Min(value = 1, message = "L'ID de filière doit être positif")
private Long filiereId;
}
6.2 Gestionnaire d'exceptions global
@RestControllerAdvice
public class GlobalExceptionHandler {
// Erreurs de validation
@ExceptionHandler([Link])
public ResponseEntity<Map<String, Object>> handleValidation(
MethodArgumentNotValidException ex) {
Map<String, String> errors = new HashMap<>();
[Link]().getFieldErrors().forEach(err ->
[Link]([Link](), [Link]())
);
Map<String, Object> body = [Link](
"status", 400,
"error", "Validation échouée",
"errors", errors,
"timestamp", [Link]()
);
return [Link]().body(body);
}
// Ressource non trouvée
@ExceptionHandler([Link])
public ResponseEntity<Map<String, Object>> handleNotFound(
ResourceNotFoundException ex) {
Map<String, Object> body = [Link](
"status", 404,
"error", [Link](),
"timestamp", [Link]()
);
return [Link](HttpStatus.NOT_FOUND).body(body);
}
// Exception générique
@ExceptionHandler([Link])
public ResponseEntity<Map<String, Object>> handleGeneral(Exception ex) {
Map<String, Object> body = [Link](
"status", 500,
"error", "Erreur interne du serveur",
"timestamp", [Link]()
);
return [Link]().body(body);
}
}
6.3 Exception personnalisée
@ResponseStatus(HttpStatus.NOT_FOUND)
public class ResourceNotFoundException extends RuntimeException {
public ResourceNotFoundException(String resource, Long id) {
super(resource + " avec l'ID " + id + " introuvable");
}
}
// Utilisation dans le service
public EtudiantDTO findById(Long id) {
return [Link](id)
.map(this::toDTO)
.orElseThrow(() -> new ResourceNotFoundException("Étudiant", id));
}
CHAPITRE 7
Spring Security & JWT
7.1 Dépendances nécessaires
<!-- Spring Security -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<!-- JWT -->
<dependency>
<groupId>[Link]</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.11.5</version>
</dependency>
<dependency>
<groupId>[Link]</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
7.2 Configuration SecurityFilterChain
@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final JwtAuthFilter jwtAuthFilter;
private final UserDetailsService userDetailsService;
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
return http
.csrf(csrf -> [Link]())
.sessionManagement(session -> session
.sessionCreationPolicy([Link]))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/auth/**").permitAll()
.requestMatchers([Link], "/etudiants/**").hasRole("USER")
.requestMatchers("/etudiants/**").hasRole("ADMIN")
.anyRequest().authenticated()
)
.addFilterBefore(jwtAuthFilter, [Link])
.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public AuthenticationManager authManager(AuthenticationConfiguration config)
throws Exception {
return [Link]();
}
}
7.3 Service JWT
@Service
public class JwtService {
@Value("${[Link]}")
private String secretKey;
@Value("${[Link]}") // 24h par défaut
private long expiration;
public String generateToken(UserDetails userDetails) {
return [Link]()
.setSubject([Link]())
.setIssuedAt(new Date())
.setExpiration(new Date([Link]() + expiration))
.signWith(getSignKey(), SignatureAlgorithm.HS256)
.compact();
}
public String extractUsername(String token) {
return extractClaim(token, Claims::getSubject);
}
public boolean isTokenValid(String token, UserDetails userDetails) {
return extractUsername(token).equals([Link]())
&& !isTokenExpired(token);
}
private boolean isTokenExpired(String token) {
return extractClaim(token, Claims::getExpiration).before(new Date());
}
private <T> T extractClaim(String token, Function<Claims, T> resolver) {
Claims claims = [Link]()
.setSigningKey(getSignKey()).build()
.parseClaimsJws(token).getBody();
return [Link](claims);
}
private Key getSignKey() {
return [Link]([Link](secretKey));
}
}
CHAPITRE 8
Tests avec Spring Boot
8.1 Test d'intégration — @SpringBootTest
@SpringBootTest(webEnvironment = [Link].RANDOM_PORT)
@AutoConfigureTestDatabase(replace = [Link])
class EtudiantIntegrationTest {
@Autowired
private TestRestTemplate restTemplate;
@Autowired
private EtudiantRepository repository;
@BeforeEach
void setUp() {
[Link]();
}
@Test
void shouldCreateAndRetrieveEtudiant() {
EtudiantDTO dto = new EtudiantDTO();
[Link]("Dupont");
[Link]("dupont@[Link]");
ResponseEntity<EtudiantDTO> response =
[Link]("/etudiants", dto, [Link]);
assertThat([Link]()).isEqualTo([Link]);
assertThat([Link]().getNom()).isEqualTo("Dupont");
}
}
8.2 Test unitaire du Controller — @WebMvcTest
@WebMvcTest([Link])
class EtudiantControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private EtudiantService service;
@Autowired
private ObjectMapper objectMapper;
@Test
void shouldReturnListOfEtudiants() throws Exception {
List<EtudiantDTO> list = [Link](
new EtudiantDTO(1L, "Alice", "alice@[Link]"),
new EtudiantDTO(2L, "Bob", "bob@[Link]")
);
when([Link]()).thenReturn(list);
[Link](get("/etudiants")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.length()").value(2))
.andExpect(jsonPath("$[0].nom").value("Alice"));
}
@Test
void shouldReturn404WhenNotFound() throws Exception {
when([Link](99L))
.thenThrow(new ResourceNotFoundException("Étudiant", 99L));
[Link](get("/etudiants/99"))
.andExpect(status().isNotFound());
}
}
8.3 Test du Repository
@DataJpaTest
class EtudiantRepositoryTest {
@Autowired
private EtudiantRepository repository;
@Test
void shouldFindByEmail() {
Etudiant e = [Link]()
.nom("Test").email("test@[Link]").build();
[Link](e);
Optional<Etudiant> found = [Link]("test@[Link]");
assertThat(found).isPresent();
assertThat([Link]().getNom()).isEqualTo("Test");
}
}
CHAPITRE 9
Configuration Avancée & Profils
9.1 Profils Spring
Les profils permettent de définir des configurations différentes pour chaque environnement
(développement, test, production). Spring Boot charge automatiquement le fichier
application-{profil}.properties correspondant.
# [Link] (commun)
[Link]=mon-api
[Link]=8080
# [Link] (développement)
[Link]=jdbc:h2:mem:devdb
[Link]-sql=true
[Link]=DEBUG
# [Link] (production)
[Link]=jdbc:postgresql://localhost:5432/proddb
[Link]=${DB_USER}
[Link]=${DB_PASS}
[Link]-sql=false
[Link]=WARN
# Activer un profil
# Via propriété
[Link]=dev
# Via variable d'environnement
SPRING_PROFILES_ACTIVE=prod java -jar [Link]
# Via argument JVM
java -[Link]=prod -jar [Link]
9.2 @ConfigurationProperties
# [Link]
[Link]=ma-cle-secrete-tres-longue-256-bits
[Link]=86400000
[Link]-origins=[Link]
@ConfigurationProperties(prefix = "app")
@Component
@Data
public class AppProperties {
private Jwt jwt = new Jwt();
private Cors cors = new Cors();
@Data
public static class Jwt {
private String secret;
private long expiration = 86400000;
}
@Data
public static class Cors {
private List<String> allowedOrigins = new ArrayList<>();
}
}
// Injection
@Service
@RequiredArgsConstructor
public class JwtService {
private final AppProperties props;
// [Link]().getSecret()
// [Link]().getExpiration()
}
CHAPITRE 10
Déploiement avec Docker
10.1 Dockerfile optimisé
# ■■ Étape 1 : Build ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
FROM eclipse-temurin:17-jdk-alpine AS builder
WORKDIR /app
COPY [Link] .
COPY src ./src
# Télécharger les dépendances Maven (mis en cache)
RUN ./mvnw dependency:go-offline -B
# Compiler et packager
RUN ./mvnw package -DskipTests
# ■■ Étape 2 : Runtime ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# Sécurité : utilisateur non-root
RUN addgroup -S spring && adduser -S spring -G spring
USER spring:spring
# Copier uniquement le JAR final
COPY --from=builder /app/target/*.jar [Link]
EXPOSE 8080
ENTRYPOINT ["java", "-XX:+UseContainerSupport", "-XX:MaxRAMPercentage=75.0", "-jar",
"[Link]"]
10.2 Docker Compose — API + PostgreSQL
version: '3.8'
services:
# ■■ Base de données PostgreSQL ■■■■■■■■■■■■■■■■■■■■■■
postgres:
image: postgres:16-alpine
environment:
POSTGRES_DB: monapp
POSTGRES_USER: ${DB_USER:-admin}
POSTGRES_PASSWORD: ${DB_PASS:-secret}
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U admin"]
interval: 10s
timeout: 5s
retries: 5
networks:
- backend
# ■■ Application Spring Boot ■■■■■■■■■■■■■■■■■■■■■■■■■■
api:
build: .
ports:
- "8080:8080"
environment:
SPRING_PROFILES_ACTIVE: prod
SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/monapp
SPRING_DATASOURCE_USERNAME: ${DB_USER:-admin}
SPRING_DATASOURCE_PASSWORD: ${DB_PASS:-secret}
APP_JWT_SECRET: ${JWT_SECRET}
depends_on:
postgres:
condition: service_healthy
networks:
- backend
volumes:
pgdata:
networks:
backend:
# Lancer l'application
docker compose up --build -d
# Voir les logs
docker compose logs -f api
# Arrêter
docker compose down
■ Utilisez toujours des variables d'environnement (.env) pour les secrets. Ne committez jamais de mots de
passe dans votre code source.
CONCLUSION & PROCHAINES ÉTAPES
Vous disposez maintenant de toutes les bases pour construire des applications Spring Boot
professionnelles : de la configuration initiale à la sécurisation JWT, en passant par la persistance JPA,
la validation, les tests et le déploiement Docker.
Pour aller plus loin, explorez :
• Spring Cloud — microservices, discovery (Eureka), load balancing
• Spring WebFlux — programmation réactive avec Project Reactor
• Spring Batch — traitement de données en masse
• Spring Cache — mise en cache avec Redis ou Caffeine
• Actuator + Micrometer — métriques et monitoring (Prometheus/Grafana)
• OpenAPI / Swagger — documentation automatique de vos APIs
■ Documentation officielle : [Link]