logo le blog invivoo blanc

Auto-configuration avec Spring Boot

20 mai 2019 | DevOps, Java

Boot est beaucoup plus qu’un générateur d’application. C’est un outil qui permet de faire de l’hyper programming ; donc, éviter d’écrire du code inutilement, démarrer rapidement et, surtout, se concentrer sur les besoins métiers de l’application, tout en restant, très flexible et en respectant les choix des utilisateurs.

Aujourd’hui, Boot représente une partie très importante de la stack Spring et il est mis en avant, du fait qu’il est le point d’entrée vers les autres Framework Spring.

Dans cet article, je vais présenter un aperçu de l’université « Maîtriser les super pouvoirs de Spring Boot» présentée par « Stéphane Nicoll » et « Brian Clozel ».

 

L’application de base avec Boot

Une application de base est comme ci-dessous.

@SpringBootApplication
public class MyApp {
public static void main(String[] args){
SpringApplication.run(MyApp.class, args;
}
]

Ici @SpringBootApplication est l’équivalent de :

  • @SpringBootConfiguration
  • @EnableAutoConfiguration
  • @ComponentScan

@ComponentScan

Permet de scanner tous les composants et les dérivés dans le package principal (package contenant la classe de configuration) et les sous packages. Il va chercher tous ce qui est annoté par @Service, @RestController, @Configuration, @Controller, @Repository, etc.

Pour éviter que certains composants ne soient pas scannés, tel le cas ci-dessous, il est préférable de créer un répertoire principal qui contiendra la classe de configuration et on dessous, on ajoutera tous les composants de l’application.

répertoire principal spring boot

répertoire principal springboot

Ce que conseille Stéphane dans ce contexte : « Si vous placez votre application Spring Boot dans un package dédié et que vous ajoutez vos composants dans cette structure, Spring Boot aura un comportement par défaut cohérent et il pourra prendre la bonne décision dans d’autres cas (typiquement dans les tests) »

 

L’auto-configuration avec Boot

Configuration de Base

Une auto-configuration est une classe de configuration (annoté par @Configuration) qui ne sera pas scannée mais listée dans un fichier spécial (META-INF/spring.factories)

En activant l’auto configuration, Boot essayera de configurer l’application, en se basant sur les dépendances définies dans l’application.

Par exemple si dans le classpath il y a référence à HSQLDB et qu’il n’y a pas de Bean qui met en place une connexion, boot sera capable de configurer une base en mémoire.

En plus, il est possible d’ajouter sa propre auto-configuration. Le cas où, par exemple, on a une librairie spécifique. Il suffi alors, d’ajouter le chemin vers le fichier de configuration dans META-INF/spring.factories

chemin vers le fichier de configuration dans META-INF/spring.factories

Jusqu’à maintenant, on a vu deux types de configuration, les Bean utilisateur et les Bean d’auto configuration.

Spring Boot : les Bean utilisateur et les Bean d’auto configuration.

Deux points:

  • On n’est pas capable de déterminer dans quel cas on peut contribuer les Bean.
  • Vu que tout ce qui est défini par l’utilisateur est traité en premier, l’auto configuration surchargera les user configuration.

Comment dans ce cas, peut on respecter les décisions prises pour l’application ?

Framework de condition

Le Framework de condition est arrivé avec Spring 4. Il est la solution pour ne pas surcharger la configuration de l’utilisateur.

Ça se concrétise par les annotations conditionnelles:

  • @ConditionalOnMissingBean è n’applique cette définition que lorsque le Bean n’existe pas, l’inverse est @ConditionalOnBean
  • @ConditionalOnMissingClassè n’applique cette configuration que lorsque la classe n’est pas présente dans le classpath, l’inverse est ConditionalOnClass.
  • @ConditionalOnWebApplicationè S’applique lorsque c’est une application web, l’inverse est @ConditionalOnNotWebApplication

L’ordre d’évaluation des conditions est des plus rapides vers les plus lentes (ce n’est pas l’ordre de déclaration).

Défini comme suit :

Srping Boot : l’ordre d’évaluation des conditions

Ces conditions peuvent être déclarées au niveau des classes et des méthodes, celles placées sur la classe sont évaluées en premier.

Il est possible aussi de créer sa propre condition, Boot offre une classe de base,  SpringbootCondition qui permet d’offrir un rapport (le mode debug doit être active dans ce cas)  pour aider l’utilisateur à diagnostiquer les classes chargées.

Conclusion

Conclusion Spring Boot

@EnableAutoConfiguration va chercher tous les fichiers spring.factories, les spring.factories vont lister tous les auto-conf, chaque autoConf contient des annotations.

Si elle ne contient que @Configuration et que toutes les conditions sont validés elle est exécutée. En deuxième étape est la validation des @Conditional sur les méthodes.

Pièges à éviter

1. Ordonnancement des classes d’auto-configuration

Exemple, On a un soucis de création des Beans si sont validés avec cet ordre.

exemple de problèmes création des Beans avec Spring Boot

Pour résoudre ceci → l’auto-conf after/before

Solution aux problèmes création des Beans Spring Boot2. ConditionalOnClass utilisé au mauvais endroit, explose au runtime → Placer plutôt la condition sur la classe de configuration pour éviter de charger la classe.

Étant donné que les conditions au niveau de la classe sont validées, Boot essayera de charger ce Bean. D’où l’exception au runtime, le cas où la bibliothèque Gson est absente.

@Configuration
public class GsonAutoconfiguration {

@ConditionalOnClass(Gson.class)
@Bean
public Gson gson() {
return new Gson();
}
}

La condition au niveau de la classe n’étant pas validée, Boot ne changera pas le Bean en l’absence de la bibliothèque Gson.

@ConditionalOnClass(Gson.class)
@Configuration
public class GsonAutoConfiguration {
@Bean
public Gson gson(){
return new Gson();
}
}

3. Vu que les configurations utilisateur et les auto-configurations sont validées en deux phases, les classes de configuration utilisateurs ne peuvent pas détecter si un Bean est manquant ou non donc ces conditions ne peuvent pas être utilisées.