Spring 2.0 et namespaces![]() Date de publication : 09 mai 2006 , Date de mise a jour : 09 mai 2006
Par
Erik Gollot Il parait que les fichiers de configuration Spring peuvent être plus clairs et plus concis avec l'arrivée de la version 2.0. Cette possibilité est offerte grâce à l'usage de namespaces XML dédiés (espaces de nommage). Il s'agit en fait de la possibilité offerte par Spring de spécifier des schémas XML comme références à la syntaxe de ses fichiers de configuration. Nous allons voir dans cet article comment se définir son propre espace de nommage et voir ainsi comment les fichiers de configuration Spring s'en trouvent simplifiés. Téléchargez la version pdf 1. De quoi s'agit-il ? 2. Ça donne quoi alors ? 3. Une vision générale 4. Construction pas à pas 4.1. Etape 1 : construire le schéma XML 4.2. Etape 2 : créer un " NamespaceHandler " 4.3. Etape 3 : créer un "BeanDefinitionParser" 4.4. Etape 4 : déclarer le " NamespaceHandler " et le schéma XML 4.5. Etape 5 : packager le tout 4.6. Etape 6 : créer le fichier de configuration qui utilise nos tags 1. De quoi s'agit-il ?
L'objectif de ce petit article est de vous présenter, à vous les " Spring addict ", cette nouveauté de la version 2.0 de Spring que sont les namespaces. Je resterai malgré tout modeste car tout ce que je raconte ici est le fruit de mes recherches sur le sujet alors que la documentation officielle n'est pas encore sortie. Vous trouverez en fin de document le lien vers l'article qui m'a fourni les premières pistes (en anglais).
Bon, les namespaces c'est quoi en quelques mots ?
Eh bien c'est un truc qui va faire que vos fichiers de configuration Spring seront beaucoup plus concis et lisibles. C'est aussi un truc qui va faire que les rédacteurs de fichier de configuration Spring seront aidés dans leur saisie et qu'ils seront plus heureux. Par contre, pour vous qui allez offrir cette facilité, c'est pas mal de boulot.
Autre point, ne vous découragez pas en lisant cet article, je sais que ce n'est pas le genre d'article que l'on lit en sirotant un bon cocktail sur une terrasse mais une fois que vous saurez faire fonctionner les namespaces, vous les adorerez, enfin j'espère. Sinon, faites une pause entre chaque paragraphe, mais c'est pas grave, comme dirait monsieur KissCool.
2. Ça donne quoi alors ?
Dans l'exemple que je vais prendre par la suite, je vais utiliser Spring pour un usage peut être peu classique,
c'est-à-dire que je vais me servir du fichier de configuration XML Spring comme une sorte de base de données.
Je vais donc y déclarer des " beans " qui seront plutôt des objets persistants plutôt que des DAO ou
autres EJB wrappers comme on le fait en général. Mais bon, l'essentiel est que vous compreniez la philosophie
de la chose.
Donc mes objets sont en fait un objet " activité " qui possède un nom et des " livrables " en entrée/sortie.
![]()
Avec un namespace approprié, voici ce que cela peut donner :
Rapidement, on voit quoi ?
Finalement, pour ceux qui connaissent les pages JSP avec les taglibs, on a les mêmes avantages. On va voir que comme pour les taglibs JSP, il va falloir écrire du code Java ; avec une petite différence c'est que Spring va encore une fois nous aider et faire une partie du travail à notre place.
Ah ! Spring, quand tu nous tiens... !
3. Une vision générale
Voyons maintenant les éléments qu'il va falloir créer pour réaliser cette prouesse. Il nous faut donc :
![]()
Il est à noter que l'utilisation d'un schéma XML pour la définition de "beans" dans le fichier de configuration Spring permet, au travers de l'usage d'un éditeur évolué (ben oui pas avec notepad ou vi !), de vérifier que les contraintes imposées par le schéma sont respectées (ce qui sera d'ailleurs aussi fait au chargement du fichier lors du lancement de votre application).
Dans le schéma qui définit votre nouveau langage de déclaration de "beans", vous pourrez donc définir des propriétés obligatoires ou optionnelles, définir des plages de valeurs pour une propriété, définir le nombre maximum d'occurrences d'une propriété, bref, tout ce que vous permet de faire les schéma XML (et donc tout cela vérifié par des éditeurs comme XMLSpy ou Eclipse WT). 4. Construction pas à pas
Bon allé, maintenant c'est parti, on ne rigole plus, on enlève les moufles et on plonge dans le vif du sujet, 1 2 3 GO !
4.1. Etape 1 : construire le schéma XML
Tout d'abord, voyons le schéma dans son ensemble et examinons chaque définition ensuite :
La définition des éléments correspondant aux objets est réalisée au travers des 2 déclarations suivantes :
Notez que ces éléments déclarent à la fois des sous-éléments et des attributs. Nous allons voir par la suite que Spring se charge d'exploiter les attributs mais l'exploitation des sous-éléments est à votre charge. Les éléments du début du fichier genre <xsd:complexType ...> permettent de définir des types de base utilisés ensuite dans la déclaration de nos éléments.
Au fait, le namespace c'est le truc http://www.mycomp.com/schema/devcom, on en reparle par la suite.
4.2. Etape 2 : créer un " NamespaceHandler "
Bon, maintenant il va falloir dire à Spring le type d'objet à créer lorsqu'il va rencontrer les tags <m:activite> et <m:livrable>. Pour cela, nous devons écrire une classe, un "NamespaceHandler".
Cette classe est en fait le représentant de notre espace de nom et est chargée de déclarer les classes qui vont, elles, faire l'association entre un tag et un "bean" à instancier.
Dans notre cas, on a créé 2 classes "parseuses" de bean, ActiviteBeanDefinitionParser et LivrableBeanDefinitionParser.
4.3. Etape 3 : créer un "BeanDefinitionParser"
Prenons d'abord l'exemple de la classe LivrableBeanDefinitionParser. Cette classe hérite d'une classe Spring , AbstractSimpleBeanDefinitionParser.
La méthode getBeanClass doit renvoyer la classe du bean que vous voulez instancier lorsque Spring rencontre le tag que vous avez associé au "BeanDefinitionParser" :
A ce stade, cela peut être la seule chose à faire au niveau de la classe " parseuse " de bean.
En effet, les attributs XML du tag m:livrable, sont automatiquement exploité par Spring comme étant des attributs d'un JavaBean. L'affectation des valeurs de ces attributs pour une instance de Livrable va donc se faire comme si vous définissiez un tag <property name="
" value="
"/> classique.
Dans notre cas, nous acceptons un tag m:livrable avec un sous-élément m:description, il nous faut donc définir la méthode postProcess pour nous même gérer ces sous-éléments qui ne sont pas pris en charge par Spring. Remarquez que si la description est saisie comme un attribut, la propriété description du bean sera positionnée par Spring automatiquement.
La méthode postProcess récupère donc le sous-élément de l'élément courant (c'est-à-dire notre tag m:livrable) portant le nom m:description. Si ce tag est trouvé, on ajoute sa valeur au builder en cours de construction par Spring : definitionBuilder.getBeanDefinition(). Le "Builder" (du pattern
Builder évidemment) correspond à la définition de la classe de notre bean en cours de construction par Spring. On lui dit donc ici qu'une propriété de nom "description" a été définie dans le fichier XML.
Regardons maintenant le cas du tag m:activite. Ce tag accepte 2 "sous-listes" (entrées et sorties), chaque élément de la liste est une référence à un livrable existant. Nous allons donc voir comme ajouter une liste de références vers d'autres beans dans le "builder" en cours de construction.
Pour cela, bien entendu, nous redéfinissont la méthode postProcess de notre grande "parseuse" de tag m:activite.
Pour faciliter l'écriture de mes "parseuses", j'ai écrit une classe BeanDefinitionParserUtil qui sait prendre en charge, de manière relativement générique un certain nombre de situations pouvant être rencontrées au niveau de sous-éléments d'une définition d'un bean.
Je vous livre donc un portion de cette classe, la portion définissant la méthode declareListRef.
La ligne : List l = DomUtils.getChildElementsByTagName(element, tagListName); récupère comme dans le code précédent le tag juste en dessous de l'élément courant. Dans notre cas, cela correspond au tag m:entrees (puis au tag m:sorties).
Dans le "if" qui suit, on récupère les sous-éléments du niveau encore en dessous, c'est-à-dire les éléments de la liste. Pour chacun des éléments de la liste, on demande l'attribut "ref" (ça c'est le truc en dur que j'ai définit de la même manière que Spring utilise l'attribut ref pour les références) et on créé un "RuntimeBeanReference" avec cette référence, chaque RuntimeBeanReference est ajoutée à la "ManagedList" que nous avons créé avant d'itérer. Enfin, la ManagedList est ajoutée au "Builder" pour dire qu'il y a été définie une propriété de type "liste de références de beans".
4.4. Etape 4 : déclarer le " NamespaceHandler " et le schéma XML
Bon , on a fait le plus gros. Maintenant, il reste à faire le liant entre tout ça Pour cela, Spring demande à ce que l'on créé 2 fichiers : spring.handlers et spring.schemas.
4.5. Etape 5 : packager le tout
Pour packager le tout, il suffit maintenant de créer un fichier JAR avec les .class de votre "tag handler", de vos "parseuses" et les 2 fichiers précédents, spring.schemas et spring.handlers, dans le répertoire META-INF du JAR.
![]() 4.6. Etape 6 : créer le fichier de configuration qui utilise nos tags
Tout est dans le sac, vous pouvez utiliser votre nouvelle librairie de tags :
Remarque : Le fichier mycomp.xsd doit être accessible via le classpath.
Voilà, c'est terminé, pour l'étape 7, si vous n'êtes pas entrain de dormir, je vous laisse le choix...
Merci à Jon pour ce premier petit article sur le sujet qui m'a permi de démarrer.
Et merci à vous d'avoir tenu jusqu'ici.
|
Copyright © 2006 Erik Gollot. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Cette page est déposée à la SACD.