...
Ce chapitre n'a pas la prétention d'être une formation à Spring. Pour plus d'informations, vous pouvez vous reporter à la documentation de springsource ( HTML / PDF ). Ne sont abordés ici que quelques éléments qui permettent détails permettant de mieux comprendre certains éléments des fichiers de configuration de esup-commons.
...
Le fichier de configuration principal (properties/applicationContext.xml) est déclaré dans le *web.xml xml* sous la forme d'un paramètre de l'application :
...
Dans esup-commons ce fichier de configuration principal contient seulement des inclusions de fichiers de configurations configuration spécialisés par domaine, comme par exemple exemple:
| Bloc de code |
|---|
<import resource="exceptionHandling/exceptionHandling.xml" /> |
...
Voyons quelques exemples...
Injection d'une chaîne de caractères
...
Dans ce cas, la méthode setRecipentEmail() sera appelée avec pour paramètre, la valeur webmaster@domain.edu.
...
On voit ici un autre aspect important de Spring qui est l'utilisation quasi systématique des interfaces. La classe CachingEmailExceptionServiceFactoryImpl (qui correspond au bean exceptionServiceFactory et contient la définition de cette propriété authenticationService) a un attribut authenticationService de type AuthenticationService. AuthenticationService est une interface. Le bean authenticationService doit donc être d'une classe qui implémente cette interface. Ceci permet d'avoir plusieurs implémentations possibles de pour cette interface et de choisir, simplement en modifiant un fichier de configuration, laquelle on utilise. Cette approche est particulièrement intéressante . Elle : elle permet, par exemple, de très facilement tester une couche de l'application en branchant des implémentations de tests des autres couches avec lesquelles le bean doit interagir.
...
| Bloc de code |
|---|
<property name="exceptionViews" >
<map>
<entry key="java.lang.Exception" value="go_exception" />
</map>
</property>
|
...
Afin de centraliser la configuration, une bonne pratique consiste à utiliser un fichier de configuration centralisant regroupant les paramètres de l'application. Ceci évite notamment de devoir modifier n fichiers différents.
...
Ici la propriété recipientEmail contiendra la valeur contenu contenue dans le paramètre exceptionHandling.email.
...
Spring n'oblige pas à saisir, dans toutes les définitions de beans, les mêmes propriétés. Pour cela, il est possible d'utiliser le mot-clé parent.
Le « parent » à a un attribut abstract="true" car il ne doit pas être créé en mémoire par Spring. Cette notation permet de se rapprocher de l'héritage Java qui est beaucoup utilisé dans esup-commons.
Exemple d'un bean « parent » ayant aussi lui-même un « parent » « parent » :
| Bloc de code |
|---|
<bean
id="abstractApplicationAwareBean"
parent="abstractI18nAwareBean"
abstract="true">
<property name="applicationService" ref="applicationService" />
</bean>
|
...
Il est, par contre, possible de sciemment introduire une dépendance avec Spring pour obtenir des services supplémentaires.
Faire en sorte que votre bean implémente l'interface InitializingBean de Spring en fait partie. Cette interface vous oblige à implémenter une méthode afterPropertiesSet qui sera appelée par Spring juste après l'initialisation du bean. Cette méthode vous permet de vérifier que toutes les propriétés sont biens bien initialisées. Si ce n'est pas le cas, vous pouvez, par exemple, lever une exception ou affecter une valeur par défaut.
On trouvera par exemple exemple :
| Bloc de code |
|---|
public void afterPropertiesSet() {
super.afterPropertiesSet();
if (!StringUtils.hasText(exceptionView)) {
exceptionView = DEFAULT\__SERVLET_\_EXCEPTION_VIEW;
logger.info(getClass() + ": no exceptionView set, using default \[" + exceptionView + "\]");
}
}
|
...
Spring offre une notion de portée (scope).
Par défaut, un bean est de portée singleton. Spring crée une seule instance de ce bean pour toute la durée d'exécution de l'application.
Il existe aussi des portées session et request qui, respectivement, permettent d'avoir une instance du bean par session utilisateur (au sens d'une application web) ou par requête (au sens HTTP). Cette notion est particulièrement intéressante pour les contrôleurs web d'une application. Les contrôleurs des applications web Ces derniers sont en général des beans de portée session, comme par exemple exemple :
| Bloc de code |
|---|
<bean id="administratorsController" class="[...].formation.web.controllers.AdministratorsController" parent="abstractContextAwareController" scope="session" /> |
Usuellement, un bean de scope request peut faire référence, via ses propriétés, à un bean de scope session ou singleton. De même, un bean de scope session peut faire référence à un bean de scope singleton. Une bonne architecture nous ammène amène d'ailleurs à utiliser dans ce sens l'injection de beans. Par défaut, la réciproque provoque une exception ... mais il est cependant possible de réaliser cette réciproque par le biais de l'aop, et cela très simplement.
Concrètement si nous voulons ici injecter le bean administratorsController qui est de scope session dans un bean de scope singleton, on utilisera la balise aop:scoped-proxy comme ceci dans la déclaration du bean administratorsController :
| Bloc de code |
|---|
<bean id="administratorsController" class="[...].formation.web.controllers.AdministratorsController" parent="abstractContextAwareController" scope="session"> <aop:scoped-proxy/> </bean> |
Pour ce faire, on aura pris soin de déclarer comme il se doit l'espace de noms aop, avec dans la balise racine du fichier de configurations configuration de beans spring Spring ceci :
| Bloc de code |
|---|
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> |
...
En mode batch par exemple, on utilisera utilisera :
| Bloc de code |
|---|
DomainService domainService = (DomainService) BeanUtils.getBean("domainService");
|
| Avertissement |
|---|
|