Project Oxygen & Ideo-LabIDEO LAB Dashboard 2026

☕ Spring Boot – Le Guide Ultime

Deep Dive : Convention/Config, DI (IoC), Starters, Web API (REST), Data JPA & Actuator.

1.1 Facile

1. C'est quoi Spring Boot ?

Framework Java "opinioné" (Convention > Config). "Just run". Serveur (Tomcat) embarqué.

Java Opinionated
1.2 Avancé

2. 💉 Cœur : DI & IoC

Inversion de Contrôle. @Autowired (Injection), @Component (Bean), ApplicationContext.

DI / IoC @Autowired
1.3 Moyen

3. Starters & Auto-Config

La "magie". spring-boot-starter-web. pom.xml (Maven). Auto-configuration.

Starters AutoConfig
1.4 Facile

4. Configuration (.yml)

application.properties vs .yml. @Value, @ConfigurationProperties.

application.yml @Value
1.5 Moyen

5. Framework : Web API (REST)

@RestController, @GetMapping, @PostMapping, @RequestBody, @PathVariable.

REST @RestController
1.6 Moyen

6. Framework : MVC

@Controller (vs Rest), Model. Templates (Thymeleaf vs JSP).

MVC Thymeleaf
2.1 Avancé

7. 💾 Data : Spring Data JPA

L'ORM "magique". @Entity, JpaRepository, Queries (findBy...), @Query (JPQL).

Data JPA ORM
2.2 Avancé

8. Plugin : Spring Security

SecurityFilterChain (@Bean). JWT vs Session. @PreAuthorize.

Security JWT
2.3 Avancé

9. Plugin : Testing

@SpringBootTest (Intégration) vs @WebMvcTest (Slice). MockMvc, @MockBean.

Test MockMvc
3.1 Moyen

10. Plugin : Actuator

Monitoring. Endpoints (/actuator/health, /metrics, /info). Prêt pour la prod.

Actuator Monitoring
3.2 Moyen

11. Historique & Versions

Boot 1 (XML-less), Boot 2 (Reactive, Java 8), Boot 3 (Jakarta, Java 17+, GraalVM).

Versions GraalVM
3.3 Avancé

12. Outils & Écosystème

start.spring.io. Maven vs Gradle. Spring Cloud (Microservices). Liens.

start.spring.io Maven
1.1 C'est quoi Spring Boot ? (Philosophie)

Spring Boot est un "accélérateur" pour le Spring Framework (l'écosystème Java/Kotlin n°1). C'est un framework "opinioné" (opinionated) qui simplifie radicalement la création d'applications "production-ready".

Le Problème (Avant Spring Boot)

Le Spring Framework classique était incroyablement puissant, mais nécessitait des *centaines* de lignes de configuration XML (beans.xml, web.xml...) juste pour démarrer. Il fallait tout configurer à la main (le serveur, la BDD, le mapping...).

La Solution (Spring Boot)

La philosophie de Boot est "Convention over Configuration" (La Convention prime sur la Configuration), inspirée de Ruby on Rails :

  • Auto-configuration : Boot "voit" les .jar dans votre projet (ex: il voit spring-boot-starter-web) et *configure automatiquement* un serveur Tomcat, Jackson (pour le JSON), etc.
  • Serveur Embarqué : Plus besoin de déployer des .war. Boot *inclut* Tomcat (ou Jetty/Undertow) dans le .jar final. L'application se lance avec une simple commande java -jar app.jar.
  • "Starters" : Des "kits" de dépendances (voir 1.3) qui simplifient la gestion (Maven/Gradle).
1.2 💉 Cœur : DI (Inversion de Contrôle)

C'est le *cœur* du Spring Framework (que Boot utilise).
IoC (Inversion of Control) : C'est le framework qui gère le cycle de vie de vos objets (les "Beans"), et non l'inverse.
DI (Dependency Injection) : C'est *comment* l'IoC fonctionne. Au lieu qu'une classe A "crée" (new) une classe B, elle la "demande" dans son constructeur, et Spring (le "conteneur") la lui "injecte".

Mauvais (Sans DI)
// Le contrôleur est "couplé" à l'implémentation
public class MonController {
    
    private final MonService service;
    
    public MonController() {
        // MAUVAIS: Le contrôleur crée sa propre dépendance
        this.service = new MonServiceImpl();
    }
    
    // ... (difficile à tester)
}
Bon (Avec DI)

Le contrôleur demande une *interface*, pas une classe.

@RestController
public class MonController {

    private final IMonService service;

    // BIEN: On "demande" la dépendance (Injection Constructeur)
    // Spring va la trouver et l'injecter.
    @Autowired
    public MonController(IMonService service) {
        this.service = service;
    }
    
    // ... (Facile à tester avec un "Mock")
}

@Service
class MonServiceImpl implements IMonService {
    // ...
}
Stéréotypes (Les "Beans")

Pour que Spring "trouve" vos classes, vous devez les annoter :

  • @Component : Le stéréotype de base ("C'est un Bean").
  • @Service : Sémantique ("C'est une logique métier").
  • @Repository : Sémantique ("C'est une classe d'accès aux données", ex: DAO).
  • @Controller / @RestController : Sémantique ("C'est un point d'entrée Web").
1.3 Starters & Auto-Configuration
Les "Starters" (pom.xml / build.gradle)

Un "Starter" n'est pas du code. C'est un descripteur de dépendances (Maven/Gradle). C'est un "kit" qui importe un ensemble de .jar cohérents.

StarterCe qu'il inclut (Auto-configure)
spring-boot-starter-webSpring MVC, Validation, Serveur Tomcat (embarqué), Jackson (JSON).
spring-boot-starter-data-jpaSpring Data JPA, Hibernate (ORM), connecteurs de BDD (HikariCP).
spring-boot-starter-securitySpring Security (filtres, protection CSRF, authentification).
spring-boot-starter-testJUnit 5, Mockito, AssertJ, MockMvc.
spring-boot-starter-actuatorEndpoints de monitoring (/health, /metrics).
L'Auto-Configuration (La "Magie")

C'est le cœur de Boot. La logique est :
1. Vous ajoutez spring-boot-starter-web à votre pom.xml.
2. Boot le voit au démarrage.
3. Il dit : "Ah, le développeur veut faire du web."
4. Il *auto-configure* (active) un Tomcat embarqué, un DispatcherServlet (le routeur), et Jackson (le convertisseur JSON).
Résultat : Vous pouvez créer un @RestController et il "juste marche", sans *une seule* ligne de XML ou de config.

1.4 Configuration (application.yml)

L'auto-configuration est "opinionée", mais vous pouvez *surcharger* (override) chaque opinion via un fichier de configuration centralisé, situé dans src/main/resources/.

application.properties (Style Java)
# Change le port du serveur (défaut 8080)
server.port=8081

# Configuration de la base de données
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=admin
spring.datasource.password=secret

# Niveaux de logs
logging.level.org.springframework.web=DEBUG
application.yml (Style YAML)

(Préféré car moins répétitif et hiérarchique)

# Change le port
server:
  port: 8081

# Configuration BDD (hiérarchique)
spring:
  datasource:
    url: jdbc:postgresql://localhost:5432/mydb
    username: admin
    password: secret
    
logging:
  level:
    org.springframework.web: DEBUG
Injecter des Propriétés (@Value)

Pour lire une propriété de configuration dans une classe :

@Service
public class MonService {

    // Injecte la valeur de la clé 'mon.secret.api'
    @Value("${mon.secret.api}")
    private String apiKey;
    
    // ...
}
1.5 Framework : Web API (REST)

C'est le cas d'usage n°1 de Spring Boot : créer des APIs REST (JSON).

Anatomie d'un @RestController
  • @RestController : Indique à Spring que cette classe est un contrôleur Web, et que ses méthodes doivent renvoyer du JSON (@ResponseBody) par défaut.
  • @RequestMapping("/api/users") : Définit l'URL de base pour ce contrôleur.
  • @GetMapping, @PostMapping, ... : Lient une méthode à un verbe HTTP et à une sous-route.
  • @PathVariable : Extrait une variable du chemin (/users/{id}).
  • @RequestParam : Extrait une variable de la query string (/search?q=...).
  • @RequestBody : Désérialise le JSON du "body" (POST/PUT) dans un objet Java (POJO).
  • ResponseEntity : Permet un contrôle total sur la réponse (status code, headers, body).
Exemple (CRUD)
// (UserDto est un simple POJO Java)
public record UserDto(long id, String name) {}

@RestController
@RequestMapping("/api/users")
public class UserController {
    
    // (Injecté par DI, voir 1.2)
    private final UserService userService;

    // GET /api/users/123
    @GetMapping("/{id}")
    public ResponseEntity<UserDto> getUserById(@PathVariable long id) {
        UserDto user = userService.findById(id);
        if (user == null) {
            return ResponseEntity.notFound().build(); // Renvoie 404
        }
        return ResponseEntity.ok(user); // Renvoie 200 + JSON
    }
    
    // POST /api/users
    @PostMapping
    public ResponseEntity<UserDto> createUser(@RequestBody UserCreateDto dto) {
        // (Le JSON est auto-validé si on ajoute @Valid)
        UserDto newUser = userService.create(dto);
        
        // Renvoie 201 Created + Header "Location: /api/users/124"
        return ResponseEntity
            .created(URI.create("/api/users/" + newUser.id()))
            .body(newUser);
    }
}
1.6 Framework : MVC (Thymeleaf)

Avant les SPAs (React/Vue), Spring était (et est toujours) utilisé pour le rendu HTML côté serveur avec le pattern MVC (Model-View-Controller).

@Controller vs @RestController
  • @RestController : Dit "renvoie du JSON (ou XML)".
  • @Controller : Dit "renvoie un *nom de template* (string) que le moteur de vue (Thymeleaf) doit interpréter".
Thymeleaf (Le "moteur de template" moderne)

Oubliez les .jsp. Le "plugin" moderne est Thymeleaf (spring-boot-starter-thymeleaf). Il permet d'écrire du HTML "naturel" avec des attributs th:.

Controller (MonController.java)
@Controller // (Pas @RestController)
public class WebController {

    @GetMapping("/hello")
    public String getHello(Model model) {
        
        // 1. Ajouter des données au "Modèle"
        model.addAttribute("username", "Alice");
        model.addAttribute("isAdmin", true);
        
        // 2. Renvoyer le nom du fichier HTML
        //    (Spring va chercher /templates/accueil.html)
        return "accueil";
    }
}
View (/templates/accueil.html)

(Nécessite spring-boot-starter-thymeleaf)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>

  <!-- 1. Afficher la variable (interpolation) -->
  <h1 th:text="|Bonjour, ${username}!|">Bonjour, Guest!</h1>
  
  <!-- 2. Condition (th:if) -->
  <div th:if="${isAdmin}">
    <p>Vous êtes admin.</p>
  </div>

</body>
</html>
2.1 💾 Data : Spring Data JPA (ORM)

Spring Data JPA n'est pas un ORM. C'est une *couche d'abstraction* (un "plugin") au-dessus d'un ORM (généralement Hibernate). JPA (Java Persistence API) est le standard, Hibernate est l'implémentation, et Spring Data JPA rend tout cela "magique".

1. L'Entité (@Entity)

C'est le Modèle (POJO) mappé à une table de BDD. (javax.persistence.* ou jakarta.persistence.* pour Boot 3+).

@Entity // (Dit à JPA: "Ceci est une table")
@Table(name = "utilisateurs")
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false, unique = true)
    private String username;
    
    // (Getters & Setters omis pour la clarté)
}
2. Le Repository (L'interface "magique")

C'est la *vraie* puissance. Vous n'écrivez *pas* l'implémentation (le DAO). Vous écrivez juste une interface qui hérite de JpaRepository.

// 1. Vous écrivez CECI :
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    
    // 2. "Derived Query" : Spring Data écrit le SQL pour vous !
    //    (SELECT * FROM users WHERE username = ?)
    Optional<User> findByUsername(String username);
    
    // (SELECT * FROM users WHERE age > ? ORDER BY username)
    List<User> findByAgeGreaterThanOrderByUsername(int age);
    
    // 3. (Optionnel) Requête custom (JPQL)
    @Query("SELECT u FROM User u WHERE u.email LIKE '%@gmail.com'")
    List<User> findAllGmailUsers();
}

// 3. Dans votre Service, vous injectez et utilisez :
@Service
public class MonService {
    @Autowired
    private UserRepository userRepo;
    
    public void demo() {
        userRepo.save(new User(...));
        List<User> users = userRepo.findByAgeGreaterThan(18);
    }
}
2.2 Plugin : Spring Security

Spring Security est le "plugin" officiel (via spring-boot-starter-security) pour gérer l'authentification (AuthN) et l'autorisation (AuthZ).

Attention : L'implémentation a *radicalement* changé depuis Spring Boot 2.7. L'ancien WebSecurityConfigurerAdapter est obsolète. La nouvelle méthode (Boot 3+) utilise des @Bean.

Exemple : Configuration Moderne (SecurityFilterChain)

Ceci définit le "pipeline" des filtres de sécurité. (Ex: pour une API REST JWT).

@Configuration
@EnableWebSecurity
@EnableMethodSecurity // (Pour @PreAuthorize)
public class SecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
            // 1. Désactiver CSRF (non-pertinent pour les APIs REST stateless)
            .csrf(csrf -> csrf.disable())
            
            // 2. Gérer la session (Stateless pour JWT)
            .sessionManagement(session -> 
                session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            
            // 3. Définir les règles d'autorisation
            .authorizeHttpRequests(authz -> authz
                // Permet l'accès à /api/auth/** (login/register)
                .requestMatchers("/api/auth/**").permitAll()
                
                // Exige l'authentification pour tout le reste
                .anyRequest().authenticated()
            );
            
        // (Ici, on ajouterait le filtre de validation JWT :
        // .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
            
        return http.build();
    }
}
Autorisation au niveau méthode (@PreAuthorize)
@RestController
@RequestMapping("/api/admin")
public class AdminController {

    // Seuls les utilisateurs avec le RÔLE 'ADMIN' peuvent appeler ceci.
    // (Nécessite @EnableMethodSecurity)
    @GetMapping
    @PreAuthorize("hasRole('ADMIN')")
    public String getAdminData() {
        return "Données Admin secrètes";
    }
}
2.3 Plugin : Testing (@SpringBootTest)

Le spring-boot-starter-test est un "plugin" qui importe JUnit 5 (framework de test), Mockito (framework de mocking), et AssertJ (assertions fluides).

@SpringBootTest (Test d'Intégration)

Charge le contexte Spring *complet* (tous les Beans, la BDD...). C'est lourd, mais teste l'intégration de bout en bout.

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class MonAppIntegrationTest {

    @Autowired
    private TestRestTemplate restTemplate; // Un client HTTP de test

    @Test
    void testRootEndpoint() {
        String body = this.restTemplate.getForObject("/", String.class);
        assertThat(body).isEqualTo("Hello World!");
    }
}
@WebMvcTest (Test "Slice")

Ne charge *que* la couche Web (le Controller). C'est beaucoup plus rapide. Les services (@Service) sont "mockés" (simulés).

@WebMvcTest(UserController.class) // Ne teste QUE ce contrôleur
class UserControllerTest {

    @Autowired
    private MockMvc mockMvc; // Simule les appels HTTP (pas de vrai serveur)

    // Simule (Mock) le service, car il n'est pas chargé
    @MockBean
    private UserService userService;

    @Test
    void testGetUser() throws Exception {
        // 1. Setup du Mock
        UserDto user = new UserDto(1L, "Alice");
        given(userService.findById(1L)).willReturn(user);
        
        // 2. Exécution & Assertions
        mockMvc.perform(get("/api/users/1"))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$.name").value("Alice"));
    }
}
3.1 Plugin : Spring Boot Actuator

Actuator (spring-boot-starter-actuator) est le "plugin" officiel pour le monitoring. Il expose des endpoints HTTP "internes" (/actuator/...) pour que les outils (Kubernetes, Prometheus) puissent vérifier l'état de l'application.

Endpoints Incontournables
EndpointDescription
/actuator/healthLe plus important. Vérifie l'état de santé (liveness/readiness).
(Renvoie {"status": "UP"}).
/actuator/infoAffiche des infos custom (ex: version git, build time).
/actuator/metricsAffiche des métriques (usage CPU, mémoire JVM, ...).
/actuator/prometheusExpose les métriques au format Prometheus (standard de monitoring).
/actuator/envAffiche les variables d'environnement (Sensible !).
Configuration (application.yml)

Par défaut (sécurité), seul /health est exposé. On doit exposer les autres manuellement :

# application.yml

management:
  endpoints:
    web:
      # Expose 'health', 'info', et 'prometheus'
      exposure:
        include: "health,info,prometheus"
        # exclude: "env" (Exclure les sensibles)
  
  # Configuration détaillée de l'endpoint 'health'
  endpoint:
    health:
      # Affiche les détails (ex: BDD connectée ? Disque OK ?)
      show-details: always
      # (Activer les "readiness" et "liveness" probes pour Kubernetes)
      probes:
        enabled: true
3.2 Historique & Versions

Spring Boot a une cadence de sortie rapide (une version majeure tous les ~2 ans), alignée sur les versions de Java.

VersionDate SortieVersion Java (Base)Nouveautés Clés
Spring Boot 1.0Avr 2014Java 6La Révolution : "Convention over Config", Auto-configuration, Starters, Serveur embarqué.
Spring Boot 2.0Mar 2018Java 8Le "Reactive Stack" : Support de Spring WebFlux (async/non-blocking) en parallèle de Spring MVC (bloquant). Java 8 requis.
Spring Boot 2.7Mai 2022Java 8Mise à jour majeure de Spring Security (abandon de WebSecurityConfigurerAdapter).
Spring Boot 3.0Nov 2022Java 17Le "Grand Saut" :
- Java 17+ requis.
- Migration de javax.* à jakarta.* (Jakarta EE 9+).
- Support natif de GraalVM (compilation AOT - Ahead-of-Time).
Spring Boot 3.2Nov 2023Java 17Support des "Virtual Threads" (Java 21).
Spring Boot 3.3Mai 2024Java 17Améliorations GraalVM, support "baseline" de Java 22.
3.3 Outils & Écosystème

L'écosystème Spring (géré par VMWare/Broadcom) est le plus vaste de l'univers Java.

Outils (Build & Démarrage)
OutilDescription
start.spring.ioLe point de départ N°1. Un générateur web ("initializer") qui crée votre pom.xml (Maven) ou build.gradle. Vous cochez les "Starters" (Web, JPA, Security) dont vous avez besoin.
Maven (pom.xml)Le gestionnaire de dépendances/build "classique" (XML).
Gradle (build.gradle)Le gestionnaire de dépendances/build "moderne" (Groovy/Kotlin). Plus rapide et plus flexible que Maven.
Frameworks "Frères" (Plugins)
  • Spring Cloud : Un "framework de frameworks" pour les microservices. (Service Discovery (Eureka), Config Server, Gateway (API Gateway), Circuit Breaker (Resilience4j)).
  • Spring Batch : Pour les traitements "batch" lourds (ex: import de masse, jobs de nuit).
  • Spring Integration : Pour l'intégration EAI (connexion à des systèmes via FTP, AMQP, ...).