Le fait de dépendre du conteneur IoC pour la création de notre application va avoir certains avantages : notre application va être plus facilement configurable. En effet, Spring Framework va pouvoir injecter pour nous des valeurs extraites de fichiers de configuration.
Nous allons également utiliser dans ce chapitre pour la première fois la classe SpringApplication qui est fournie spécifiquement par Spring Boot. Il est recommandé d’utiliser cette classe pour démarrer une application Spring Boot afin de bénéficier des mécanismes d’auto-configuration.
Comme nous l’avons précisé dans notre chapitre d’introduction, Spring Boot n’est pas une évolution ou une nouvelle version du Spring Framework. Il s’agit d’une extension destinée à simplifier la création d’application en se basant sur des mécanismes de configuration automatique.
Une application Spring Boot utilise la classe SpringApplication. Cette classe fournit la méthode statique run.
La base d’une application Spring Boot.
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}La méthode run attend en paramètres la classe qui va servir de base pour la création du contexte d’application et la liste des paramètres de lancement de l’application. La méthode run a pour responsabilité de créer un contexte d’application mais elle a aussi la charge de deviner le comportement attendu (Par exemple, nous verrons dans le chapitre Les applications Web avec Spring Web MVC que si nous activons le support pour une application Web, l’appel à la méthode run va également lancer un serveur Web embarqué).
Cette méthode run retourne une instance de ConfigurableApplicationContext. Contrairement à une application Spring classique, il n’est pas nécessaire de fermer le contexte d’application ainsi créé, Spring Boot s’en chargera à la fin de l’exécution de notre méthode main. Ainsi, la classe de lancement d’une application Spring Boot se limite souvent au code donné ci-dessus.
L’annotation @SpringBootApplication est équivalente à @Configuration et @ComponentScan (plus d’autres choses). Il n’est donc pas nécessaire d’ajouter ces annotations. Si on souhaite configurer la détection de beans, l’annotation @SpringBootApplication fournit les attributs nécéssaires (scanBasePackages et scanBasePackageClasses qui sont équivalents aux attributs basePackages et basePackagesClasses de l’annotation @ComponentScan).
Ce fichier est utilisé pour paramétrer le comportement par défaut de l’application. En fonction des dépendances déclarées dans notre projet et en fonction de la valeur des propriétés présentes dans ce fichier, Spring Boot va adapter la création du contexte d’application. Nous verrons que cela simplifie considérablement le développement d’une application Web et l’interaction avec les bases de données.
Nous avons vu qu’il est possible d’utiliser l’annotation @Value pour injecter une valeur dans une propriété.
Dans la valeur à injecter, nous pouvons utiliser la syntaxe ${ } pour donner le nom d’une propriété. Alors c’est la valeur extraite du fichier application.properties qui sera injectée. Il est donc facile d’extraire n’importe quelle valeur de configuration pour notre application.
Si nous reprenons notre exemple d’un fournisseur de connexion à une base de données en utilisant l’API JDBC, nous pouvons très facilement extraire la configuration nécessaire dans le fichier application.properties.
@Component
public class SimpleConnectionProvider implements Supplier<Connection> {
@Value("${database.uri}")
private String databaseUri;
@Value("${database.login}")
private String login;
@Value("${database.password}")
private String password;
private Connection connection;
@PostConstruct
public void openConnection() throws SQLException {
connection = DriverManager.getConnection(databaseUri, login, password);
}
// ...
}database.uri = jdbc:mariadb://localhost:3306/db
database.login = root
database.password = r00tLe type de la valeur à injecter ne se limite pas à une chaînes de caractères. Le Spring Framework est capable de réaliser une conversion de type. Ainsi, on peut injecter des primitives (nombres, valeurs booléennes, caractères). On peut également injecter un objet de n’importe quel type.
@Component
public class RemoteServerAccess {
@Value("${remote.server.url}")
private URL url;
// ...
}remote.server.url = http://localhost/accessSi la propriété n’existe pas, la valeur correspond à la chaîne de caractères donnée directement dans @Value. Cependant, il est possible de fournir une valeur par défaut avec la syntaxe :
${propriete : valeur}Exemple :
@Value("${remote.server.timeout : 1000}")
private int timeout;Une application Spring Boot supporte par défaut l’utilisation d’un fichier application.properties. Mais si on ne souhaite pas utiliser Spring Boot ou que l'on peut ajouter des fichiers de configuration supplémentaires, on peut utiliser l’annotation @PropertySource pour désigner l’emplacement du fichier ou des fichiers de propriétés.
@SpringBootApplication
@PropertySource("classpath:config.properties")
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}L’annotation @Value ne permet pas uniquement d’injecter des propriétés, nous pouvons également injecter des variables d’environnement. Par exemple, sous un système Linux, il existe la variables d’environnement USER qui donne le login de la session en cours. Pour récupérer sa valeur par injection :
@Value("${USER}")
private String user;Si on a besoin de réaliser des traitements plus complexes à partir des propriétés, on peut demander à injecter un bean de type Environment. Cette interface définie par le Spring Framework, qui permet d’accéder à la valeur des propriétés de l'application en appelant une de ses méthodes (telles que getProperty).
@Autowired
private Environment env;Spring Boot propose une version avancée de la configuration d’une application. Il s’agit de représenter les données présentes dans un fichier de propriétés sous la forme d’un bean avec les annotations @Configuration et @ConfigurationProperties.
Exemple du bean "./src/main/java/fr/enterprise/app_config/DatabaseConfig.java".
Attention, la présence des setters est obligatoire pour signaler à Spring quelles propriétés doivent être injectées.
On peut ensuite revoir la déclaration du bean de connexion en injectant ce nouveau bean de configuration :
"./src/main/java/fr/enterprise/app_config/SimpleConnectionProvider.java".
Une classe annotée avec @ConfigurationProperties peut également profiter de la validation déclarative en utilisant l’API standard Bean Validation.
L’API standard Bean Validation (doit être importé comme dépendance) permet d’ajouter des contraintes sur les attributs d’une classe afin de réaliser une validation sur leur valeur. Elle peut être utilisée dans différents contextes et nous verrons qu’elle peut être très utile pour valider les données envoyées par un utilisateur dans une application Web développée avec Les applications Web avec Spring Web MVC.
Exemple dans Spring MVC :
public class UserService {
public void createUser(@Email String email, @NotNull String name) { }Exemple dans notre contexte :
@NotNull(message = "password is mandatory but can be left empty")
private String password;Une grande liberté est donnée aux développeurs.
Exemple : Il est possible de stocker la configuration de son application non pas dans un fichier de propriétés mais dans un fichier YAML. Il est également possible de gérer des profils d’exécution pour mieux contrôler l’instanciation des beans et les paramètres de configuration.