Depuis son apparition en 2014, Spring Boot a changé la manière de développer des applications Java. Là où Spring Framework exigeait souvent de longues configurations XML ou Java, Spring Boot a proposé une approche « convention over configuration » : des choix par défaut sensés, et la possibilité d’overrider facilement via des propriétés.
Les starters Spring Boot participent à cette philosophie. Ils regroupent des dépendances et des auto-configurations prêtes à l’emploi, pour permettre aux développeurs de se concentrer sur la logique métier plutôt que sur l’infrastructure.
Dans un projet d’entreprise ou dans un écosystème plus large, écrire ses propres starters permet d’encapsuler des pratiques communes : sécurité, journalisation, observabilité, connexion aux bases de données internes, etc.
Cet article montre pourquoi et comment écrire un starter personnalisé, en prenant comme exemple un starter minimaliste
Présentation des starters Spring Boot
Un starter Spring Boot, au sens large, est une dépendance qui fournit :
- Des dépendances Maven : par exemple
spring-boot-starter-webinclut automatiquement Spring MVC, Tomcat, Jackson, etc. - Une auto-configuration : un mécanisme qui crée et configure automatiquement des beans dans le context Spring si certaines conditions sont réunies.
Le mécanisme repose sur :
- l’annotation
@Configuration(ou@AutoConfigurationdepuis Spring Boot 3), - les conditions comme
@ConditionalOnClass,@ConditionalOnMissingBean,@ConditionalOnPropertyqui définissent quand l’auto-configuration s’active, - un fichier de déclaration
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
⚖️ Avantages et inconvénients de créer ses propres starters
➕ Avantages
- Réduction de la duplication : Au lieu de recopier des dizaines de lignes de configuration dans chaque projet, on les centralise dans un starter.
- Facilité d’onboarding : Un nouveau projet ou un nouvel arrivant dans l’équipe n’a qu’à ajouter une dépendance Maven pour obtenir une configuration cohérente.
- Uniformisation :Tous les projets utilisent la même version des dépendances, la même configuration par défaut, et appliquent les mêmes standards.
- Personnalisation contrôlée : Les starters exposent des
@ConfigurationProperties: l’utilisateur final peut personnaliser les valeurs dansapplication.propertiesouapplication.yml. - Productivité accrue : Moins de temps perdu à configurer, plus de temps pour coder le métier.
➖ Inconvénients
- Risque de sur-configuration : Un starter trop intrusif peut imposer des choix difficiles à contrecarrer. Il faut toujours laisser la possibilité de désactiver ou de remplacer les beans.
- Maintenance : Un starter doit être maintenu : mises à jour des dépendances, compatibilité avec les nouvelles versions de Spring Boot, corrections de sécurité.
- Compatibilité multi-version : Entre Spring Boot 2 et 3, les mécanismes de déclaration d’auto-configuration ont changé (
spring.factoriesvsAutoConfiguration.imports). Il faut choisir sa cible ou supporter les deux. - Complexité de test : Bien que Spring propose des outils (
ApplicationContextRunner), écrire des starters testés et fiables exige une certaine discipline.
Exemple : un starter minimaliste
Pour illustrer, nous utilisons greeting-starter, un starter très simple qui fournit un service d’accueil configurable.
Classe d’auto-configuration : GreetingAutoConfiguration
@Configuration
@ConditionalOnClass(GreetingService.class)
@EnableConfigurationProperties(GreetingProperties.class)
public class GreetingAutoConfiguration {
private final GreetingProperties properties;
public GreetingAutoConfiguration(GreetingProperties properties) {
this.properties = properties;
}
@Bean
public GreetingService greetingService() {
return new GreetingService(properties);
}
}Rôle et utilité :
@Configuration: indique que cette classe contient des définitions de beans Spring.@ConditionalOnClass(GreetingService.class): l’auto-configuration ne sera activée que si la classeGreetingServiceest présente sur le classpath. Cela permet d’éviter les erreurs si la dépendance est absente.@EnableConfigurationProperties(GreetingProperties.class): indique à Spring Boot de lier automatiquement les propriétés définies dansGreetingPropertiesaux valeurs deapplication.propertiesouapplication.yml.greetingService(): méthode annotée@Beanqui crée le beanGreetingService. C’est le service que l’utilisateur final pourra injecter directement dans ses composants.
Classe de propriétés : GreetingProperties
@ConfigurationProperties(prefix = "greeting")
public class GreetingProperties {
private String message = "Hello, World!";
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}Rôle et utilité :
- Contient les paramètres configurables de notre starter. Ici, uniquement le message de salutation.
prefix = "greeting": toutes les propriétés commençant pargreeting.dansapplication.propertiesseront mappées automatiquement sur les champs de cette classe.- Valeur par défaut (
Hello, World!) : permet d’avoir un comportement fonctionnel même si l’utilisateur n’écrit pas de configuration personnalisée.
Service fourni : GreetingService
public class GreetingService {
private final GreetingProperties properties;
public GreetingService(GreetingProperties properties) {
this.properties = properties;
}
public String greet() {
return properties.getMessage();
}
}Rôle et utilité :
- C’est le cœur fonctionnel du starter : il expose une méthode
greet()qui retourne le message configuré. - Injecte
GreetingPropertiespour récupérer la valeur du message configuré par l’utilisateur. - Peut être facilement injecté dans n’importe quel composant Spring grâce à l’auto-configuration.
Déclaration de l’auto-configuration
Dans vos resource ajoutez un fichier META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
qui contiendra
xxxxx.yyyyyy.configuration.GreetingAutoConfigurationRôle et utilité :
- Indique à Spring Boot quelles classes d’auto-configuration doivent être chargées automatiquement lors du démarrage.
- Depuis Spring Boot 3, ce fichier remplace le mécanisme historique
spring.factories. - Chaque ligne correspond à une classe d’auto-configuration qui sera scannée et instanciée si les conditions sont remplies.
Utilisation dans l’application cliente
Dans l'application ou vous souhaitez utiliser votre starter, vous n'avez qu'à importer la dépendance vers ce dernier dans votre fichier pom.xml :
<dependency>
<groupId>fr.eletutour</groupId>
<artifactId>greeting-starter</artifactId>
<version>${project.version}</version>
</dependency>Et ajouter la properties à surcharger dans votre fichier application.properties :
greeting.message=Hello from custom starter!Il ne vous reste plus maintenant qu'à utiliser le service configuré dans le starter.
@SpringBootApplication
public class GreetingApplication implements CommandLineRunner {
private static final Logger LOG = LoggerFactory.getLogger(GreetingApplication.class);
private final GreetingService greetingService;
public GreetingApplication(GreetingService greetingService) {
this.greetingService = greetingService;
}
public static void main(String[] args) {
SpringApplication.run(GreetingApplication.class, args);
}
@Override
public void run(String... args) {
LOG.info(greetingService.greet());
}
}GreetingServiceest injecté automatiquement grâce à l’auto-configuration.CommandLineRunnerpermet de vérifier immédiatement le fonctionnement du starter en affichant le message configuré au démarrage.- L’utilisateur final n’a aucune configuration supplémentaire à écrire : le starter s’occupe de tout.
Au démarrage de l'application nous aurons une ligne de log affichant le message configuré :
2025-09-25T08:49:19.081+02:00 INFO 81860 --- [ main] fr.eletutour.GreetingApplication : Hello from custom starter!Et la suite ? Vers un starter plus complet
L’exemple greeting-starter que nous avons vu est volontairement minimaliste : il expose un seul service et une seule propriété. Mais les concepts que nous avons appliqués peuvent être étendus pour créer des starters beaucoup plus riches et réutilisables dans des projets professionnels. Voici quelques pistes pour aller plus loin :
Multiples services et beans configurables
Plutôt que de se limiter à un simple GreetingService, un starter peut fournir plusieurs services liés, par exemple :
- un service de traduction (
TranslationService) qui adapte les messages à la langue de l’utilisateur, - un service de logging ou de traçabilité des messages (
MessageAuditService), - un service de formatage configurable (
MessageFormatter) qui applique des styles ou des templates.
Chacun de ces services pourrait être activé ou désactivé selon des propriétés spécifiques, et être conditionné par @ConditionalOnMissingBean pour permettre aux applications clientes de les surcharger.
Propriétés hiérarchiques et dynamiques
Au lieu d’une seule propriété message, on pourrait imaginer :
greeting.default-message=Hello
greeting.farewell-message=Goodbye
greeting.style=uppercase
greeting.enabled=trueCes propriétés pourraient être liées à une classe GreetingProperties enrichie, avec des comportements différents selon la configuration. Cela permet de gérer plusieurs cas d’usage depuis un même starter.
Prise en charge de profils et d’environnements
Un starter peut détecter le profil Spring actif (dev, prod, test) et adapter ses beans ou valeurs par défaut en conséquence :
- un message différent en développement pour le debugging,
- un message en production plus formel,
- des fonctionnalités désactivées dans les tests pour alléger le contexte Spring.
Intégration avec d’autres frameworks ou librairies
On pourrait imaginer que notre starter interagisse avec :
- Spring Security pour limiter qui peut utiliser certaines fonctionnalités du service,
- Spring Web pour exposer une API REST de messages configurables,
- un système de cache ou de base de données pour stocker des messages personnalisés.
Conclusion
Écrire son propre starter Spring Boot, c’est investir dans la simplicité et la cohérence. Comme nous l’avons vu avec greeting-starter, quelques classes suffisent pour exposer une configuration réutilisable et personnalisable.
Dans un contexte d’équipe ou d’organisation, les starters deviennent de véritables briques de standardisation, réduisant la dette technique et favorisant la productivité. Leur principal défi est la maintenance : veiller à leur compatibilité, documenter leurs propriétés, et les tester régulièrement.
En définitive, les starters ne doivent pas être vus comme une fin en soi, mais comme un outil pour encapsuler ce qui doit être commun, sans priver les projets de leur liberté.
La règle d’or : proposer des valeurs par défaut utiles, mais toujours faciles à override.
Tout le code relatif à cet article est trouvable ici :