Spring Boot : Ce qu’il ne fera jamais, mais que tu devras maîtriser quand même
🧙♂️ Ce que Spring Boot ne fera jamais à ta place (et pourquoi c’est une bonne nouvelle)
Spring Boot, c’est un peu comme cette voiture automatique hyper agréable à conduire.
Tu démarres sans caler, tout est fluide… jusqu’au jour où tu veux passer la marche arrière en pleine descente sans comprendre pourquoi ça couine.
Beaucoup de développeurs (moi y compris, au début) font confiance aveuglément à Spring Boot. Il faut dire qu’il rend le démarrage d’un projet diablement rapide. Mais à trop s’appuyer sur sa magie, on oublie parfois ce qu’on fait vraiment — et c’est là que les vrais problèmes commencent.
Dans cet article, je partage des cas concrets que j’ai rencontrés ou observés en mission, et qui montrent clairement que :
Spring Boot est ton allié, mais il n’est pas ton coéquipier DevOps, ton mentor Java ni ton testeur QA.
🟢 Ce que Spring Boot fait très bien pour toi
Soyons objectif, voici ce que j’adore dans l’écosystème SpringBoot :
spring-boot-starter-*
: tu déclares ta dépendance, tu compiles, tu exécutes et ça fonctionne- Embedded Tomcat : fini le packaging avec des WARs
- Auto-configuration : plus besoin de 20 fichiers XML
- Spring Initializr : démarrer un nouveau projet n’a jamais été aussi rapide
- Spring Actuator : endpoints de santé, metrics, logs… top pour le monitoring.
Mais c’est justement parce que ça semble si simple qu’on oublie que beaucoup de choses sont implicites.
🔥 Ce que Spring Boot ne fait pas à ta place
1. Comprendre le cycle de vie de ton application
Cas réel : un collègue utilisait @PostConstruct
pour initialiser un cache, pensant que tout était prêt à ce moment-là.
Résultat : NullPointerException
en production, car certains beans n’étaient pas encore complètement initialisés.
💡 Ce qu’il faut savoir :
@PostConstruct
est exécuté juste après l’injection des dépendances, mais avant certaines phases d’initialisation des proxys ou d’autres beans dépendantsCommandLineRunner
etApplicationRunner
sont exécutés après la création complète du contexte Spring, mais leur ordre d’exécution peut varier selon leur priorité- Lorsque tes services s’appellent entre eux, il faut veiller à bien gérer la dépendance et l’ordre d’initialisation des beans, notamment pour éviter les boucles ou des états partiellement initialisés
2. Gérer ta configuration de manière fiable
Contexte : une variable spring.datasource.url
était bien définie dans le fichier application-dev.yml
.
Mais en recette, la variable d’environnement SPRING_DATASOURCE_URL
a surchargé la configuration, sans que personne ne s’en rende compte.
Ce que Spring Boot fait :
- Il fusionne les propriétés provenant de plusieurs sources (fichiers YAML, variables d’environnement, arguments JVM…)
- Il applique une priorité dans cette fusion, ce qui signifie qu’une valeur peut être silencieusement surchargée par une autre source
🛑Mais il ne t’avertit pas quand une valeur est surchargée
✅ Astuce : utilise l’endpoint Actuator /env
pour vérifier la configuration effective en temps réel, et ajoute des logs explicites au démarrage pour les propriétés sensibles.
3. Sécuriser réellement ton application
Oui, spring-boot-starter-security
ajoute une page de login par défaut.
Mais non, ça ne sécurise pas forcément ton API REST, ni tes endpoints /actuator
, ni tes pages d’erreur.
Exemple :
- Un dev pensait que ses endpoints étaient protégés car “il avait mis Spring Security”
- Résultat : tous les endpoints étaient accessibles en GET/POST, sans restrictions ni rôles
✅ Ce que tu dois faire :
- Configurer explicitement ta
SecurityFilterChain
avec les règles d’accès pour chaque endpoint - Gérer finement les rôles, CORS, CSRF, tokens JWT…
- Restreindre les accès à
/actuator
,/swagger-ui
,/h2-console
selon les environnements
4. Optimiser les performances au démarrage
Un microservice démarrait en 18 secondes, ce qui faisait planter Kubernetes à cause d’un timeout.
Analyse :
- Trop de classes scannées automatiquement, incluant des packages inutiles
- Présence de starters inadaptés (
spring-boot-starter-jdbc
dans un projet MongoDB) - Aucun profil actif défini, donc la conf par défaut s’appliquait partout
✅ Astuces :
- Limite le scan des composants via
@ComponentScan(basePackages = {"com.ton.projet"})
- Exclue les auto-configurations non utilisées avec
@SpringBootApplication(exclude = ...)
- Active un profil par défaut en développement (par exemple
spring.profiles.active=dev
dansapplication.properties
) pour éviter les comportements imprévus
⚠️ En production, ne mets jamais un profil de développement actif ! Utilise plutôt des profils prod
adaptés, avec leurs propres configurations (exemple : application-prod.yml
et variables d’environnement associées). Cette séparation claire évite les erreurs de configuration et garantit des performances optimales.
5. Maîtriser les effets des annotations Spring
Spring est un royaume d’annotations, mais elles ne fonctionnent pas toujours comme on l’imagine.
Voici un exemple classique, avec des noms génériques :
@Service
public class OrderService {
@Transactional
public void processOrder() {
// traitement principal
this.updateInventory(); // pas de rollback si exception ici !
}
@Transactional
public void updateInventory() {
// mise à jour du stock
}
}
⚠️ Problème : l’appel interne à updateInventory()
ne passe pas par le proxy Spring, donc la gestion transactionnelle annotée n’est pas activée. En cas d’exception dans updateInventory()
, la transaction globale ne sera pas annulée.
✅ Bonnes pratiques :
- Ne pas invoquer à l’intérieur d’une même classe des méthodes annotées @Transactional, car cela contourne la gestion des transactions par Spring
- Découpler avec des appels externes ou via un événement
- Vérifier le proxy Spring (via
AopContext
ou utilitaires Spring)
6. Écrire du code maintenable
Spring Boot permet un développement rapide. Mais ce n’est pas une carte blanche pour faire n’importe quoi.
J’ai vu un projet avec :
- 4 000 lignes dans la classe principale
Application.java
- Des services qui font aussi office de DAO
- Des contrôleurs qui manipulent directement du JSON sans sérialisation
Spring ne t’empêche pas cela. Il t’encourage presque, si tu ne mets pas en place toi-même des règles.
✅ Ce que je recommande :
- Séparer clairement les couches : contrôleurs, services, repositories
- Documenter ta configuration (README.md, diagrammes d’architecture, fichiers
application-example.yml
) - Documenter aussi tes APIs avec Swagger/OpenAPI ou autre outil adapté
- Écrire des tests automatisés (unitaires et d’intégration) dès le début
🧩 Checklist personnelle avant livraison
Avant de livrer une appli Spring Boot, je vérifie systématiquement :
- Tous les endpoints sensibles sont correctement protégés
- La configuration effective est loggée clairement au démarrage
- Aucun starter ou auto-configuration inutile n’est présent
- Les annotations transactionnelles et asynchrones sont bien testées et comprises
- Un profil
prod
est défini avec une configuration dédiée - L’application démarre en moins de 5 secondes, même en production
🤝 Conclusion
Spring Boot est un excellent outil. Mais ce n’est pas un raccourci vers la qualité.
C’est comme un bon couteau de cuisine : il coupe très bien… mais il faut savoir s’en servir.
En tant que développeur, tu n’as pas le luxe de “faire confiance à la magie”.
Tu dois livrer du code :
- que tu comprends
- que tu peux maintenir
- et que ton client pourra faire évoluer sans toi (car oui, un bon code doit pouvoir être repris par n’importe quel développeur de l’équipe, tu n’es pas indispensable)
💬 Et toi ?
Quels sont les pièges Spring Boot que tu as rencontrés ?
Tu préfères faire quoi “à la main” pour garder le contrôle ?
#java #softwarearchitecture #webdevelopment #springboot #bestpractices