« The Spring Framework provides a comprehensive programming and configuration model
for modern Java-based enterprise applications »
Comprenez que Spring est un "couteau suisse" pour faciliter la vie du développeur Java, spécialement si il développe pour Java EE (mais pas que).
La vidéo suivante est une présentation générale de Spring illustrant les concepts mis en oeuvre dans Spring.
Transparents présentés dans la vidéo
Le coeur de Spring est un moteur d'injection de dépendances permettant l'inversion de contrôle (en anglais IoC pour Inversion of Control) du cycle de vie des objets. L'IoC permet, entre autre, de "repousser" le choix d'implémentation (ou d'instance) d'un objet inclus dans un autre.
Prenons l'exemple d'un DAO JPA ou JDBC. Imaginons que le développeur de notre interface ne soit pas le même que celui qui réalise la couche de persistance (donc du DAO). Le développeur de l'interface ne connait pas la classe qui sera utilisée, et d'ailleurs il n'a pas envie de faire un new xxxJPADao()
, ce qui "casserait" en parti l'abstraction que nous avons essayé de mettre en place. De l'autre coté, le développeur de notre DAO ne sait pas où et comment son implémentation JPA sera utilisée. Il ne peut pas faire view.setDao( ... )
Heureusement il y a Spring. Dans l'interface, on demandera à l'injecteur de dépendances de trouver et d'affecter le DAO, de l'autre on déclarera l'implémentation JPA comme composant DAO à être utilisé. Le tout sera initialisé et affecté au lancement de l'application.
Merci Martin, que ferions-nous sans toi.
pour votre culture générale : Inversion of Control Containers and the Dependency Injection pattern
Le principe est de construire des objets, que l'on nommera "composant" et de les mettre à disposition des autres composants.
Un composant est une instance partagée du contexte Spring, selon le pattern "singleton" par défaut.
Une annotation @Component
permet de définir une classe Java comme un composant Spring. Dans ces objets il sera possible d'utiliser l'annotation @Autowired
pour injecter automatiquement une instance présente dans le contexte et possédant un type compatible.
Si une injection ne peut pas être satisfaite, alors une erreur sera levée au démarrage du contexte spring.
Certaines injections pouvant être facultatives, vous pouvez mettre le paramètre "required=false" dans l'annotation Autowired.
Il existe différentes implémentations de contexte Spring. Nous utiliserons généralement AnnotationConfigApplicationContext
comme instance d'ApplicationContext
. Cette implémentation permet de configurer un contexte Spring à l'aide des annotations que nous avons placées.
Spring peut rechercher tous les composants (ceux annotés) dans une partie du classpath : cela se configure à l'aide de l'annotation @ComponentScan
. Spring inspectera la liste des packages passés en paramètre pour constituer son contexte, à l'aide des composants qui y sont définis.
La lecture de la documentation de référence concernant les beans et surtout ce paragraphe vous serons sans doute d'une aide précieuse.
L'intérêt de Spring est surtout de réaliser des scénarii d'injection lorsque les objets proviennent de librairies différentes, ou lorsque plusieurs implémentations d'une même classe peuvent être utilisées dans l'application.
L'inspection des composants du classpath peut se faire dans vos packages ou ceux définis dans une autre librairie (jar).
@Configuration
.
Si généralement nous préférons mettre des annotations pour configurer un contexte Spring, il est effectivement possible d'utiliser des fichiers de configuration en XML. Historiquement, c'est la manière dont on configurait un contexte Spring. Les deux approches (annotations / XML) ont leurs avantages et inconvénients.
Le screencast suivant montre comment créer un contexte spring basique constitué de quelques composants. Il présente une approche à l'aide d'annotations et celle à l'aide de fichiers de description xml.