# Java > Gnral Java > Persistance des donnes >  Annotations - Un cas d'application pour la dsrialisation avec XStream

## bobuse

Salut le forum,

Un petit article sous forme de post, en esprant avoir vos avis/retours.

L'objectif est de montrer une utilisation concrte des annotations et de l'introspection, afin de montrer leur intrt. Pour moi, l'intrt majeur est la possibilit d'ajouter des fonctionnalits dans un code source sans trop en altrer la structure.

*Contexte*

J'utilise la bibliothque XStream pour srialiser et dsrialiser des objets Java. En particulier dans le cadre du dveloppement d'un framework, l'utilisateur du framework spcialise des objets par hritage et ajoute des proprits  ces objets. L'intrt d'XStream est alors d'obtenir un fichier XML qui permet d'initialiser toutes ces proprits qui sont ensuite utilises dans le framework.

*Limite d'Xstream*

Xstream utilise le mot-cl _transient_ pour exclure des attributs de classe du processus de srialisation et dsrialisation. C'est trs pratique dans mon cas, puisque les attributs de classe dfinis par l'utilisateur peuvent des proprits intressantes pour la configuration du comportement global, mais ces attributs peuvent aussi n'tre que fonctionnels et servir  stocker des objets lis au calcul par exemple.

Dans le processus de dsrialisation, touts les attributs proprits (non _transient_) sont donc correctement initialiss. En revanche, j'ai aussi souvent besoin d'initialiser les attributs fonctionnels (_transient_) avant toute excution de mon processus global.

*Exemple*

Par exemple, si dans une de mes classes, j'utilise une distribution statistique pour gnrer des nombres pseudo-alatoires qui a besoin de deux paramtres pour s'initialiser, j'aurai trois attributs dans ma classe, les deux paramtres de la distribution (non _transient_), et l'objet reprsentant ma distribution qui lui est purement fonctionnel et sera donc _transient_.

Ce qui donne quelquechose comme a :


```

```

Une fois ma classe dsrialise, j'aurai mes attributs a et b correctement initialiss, par contre l'attribut maDistribution sera _null_.
Il faut donc que je cre une mthode qui effectuera cette initialisation, par exemple :


```

```

Oui mais ensuite comment appeler cette mthode au bon moment dans le processus de dsrialisation ?

Une solution pourrait bien sr de dfinir une interface avec une mthode qui serait appele systmatiquement. Il suffirait donc que _MaClasse_ implmente cette interface, et dfinisse le corps de la fonction spcifi par l'interface. Ce serait simple.
Oui, mais. Cette tape d'initialisation n'est pas systmatique, et obligerait donc  mettre la fonction de l'interface avec un corps vide.

Et c'est l que l'annotation est utile. Car elle va permettre de proposer une fonctionalit qui est trs peu invasive dans le code.

*L'annotation et son utilisation*

Voil l'annotation que je dfinis :


```

```

L'utilisation est simple, il suffit d'annoter la mthode que l'on veut excuter  l'initialisation, comme cela :


```

```

Ensuite comment appeler les mthodes annotes ? Et bien, en plus de l'annotation, j'ai dfini deux mthodes.
La premire permet de rcuprer les mthodes annotes de la sorte dans une classe, en prenant soin de chercher ces mthodes dans toutes les super-classes :


```

```

Et la deuxime qui permet  l'aide de la premire, d'excuter ces mthodes sur un objet :


```

```

 partir de l, je peux dans mon framework, aprs avoir dsrialiser un objet, appeler la mthode _callAnnotedMethods_ sur cet objet pour effectuer les ventuels traitement d'initialisation.

*Remarques*

 La mthode annote ne doit pas avoir d'argument, sinon une exception est leve L'introspection ncessaire pour obtenir les mthodes annotes a un certain cot  l'excution. Dans mon contexte, il ne s'agit que de la phase d'initialisation qui est ngligeable par rapport  l'excution complte. Il y avait peut-tre d'autres solutions possibles, mais je n'ai pas trop cherch. Cette solution me paraissait simple et sduisante.

Merci de m'avoir lu  ::):

----------


## adiGuba

Salut,


Les annotations permettent en effet plein de chose et peuvent tre trs utile !

Dans ton cas une solution avec une interface aurait pu tre plus simple  implmenter, puisqu'il aurait suffit de vrifier que l'objet implmente bien l'interface :



```

```

Mais les annotations apportent ici deux avantages : on peut utiliser n'importe quelle mthode (avec n'importe quelle visibilit), et on peut utiliser plusieurs mthodes d'initialisation...


Juste une remarque toutefois : vites d'appeler *setAccessible()* dans tous les cas. Il vaudrait mieux le faire seulement en cas de besoin :


```

```

En effet *setAccessible()* ncessite certains droits qui ncessitent de signer l'application si elle est dploy par JavaWebStart ou en applet.
Or si c'est pour appeler une mthode *public* c'est un peu dommage  :;): 






> La mthode annote ne doit pas avoir d'argument, sinon une exception est leve


A ce propos il existe un mcanisme qui permet de contrler cela ds la compilation : APT (Annotation Processing Tool). Grosso modo  la compilation tu peux rechercher les lments annot et les vrifier (avec une API proche de celle de la rflection).

J'en parle dans mon tutoriel sur les Annotations de Java 5.0, toutefois ce n'tait pas standard et cela impliquait d'utiliser un compilateur spcifique (*apt* justement).

C'est devenu standard avec *Java 6*, mme si cela a t grandement modifi (je n'ai malheureusement pas encore eu le temps d'y jeter un coup d'oeil).

a++

----------


## bobuse

> Salut,
> 
> 
> Les annotations permettent en effet plein de chose et peuvent tre trs utile !
> 
> Dans ton cas une solution avec une interface aurait pu tre plus simple  implmenter,[...]
> 
> Mais les annotations apportent ici deux avantages : on peut utiliser n'importe quelle mthode (avec n'importe quelle visibilit), et on peut utiliser plusieurs mthodes d'initialisation...


Oui, le fait de pouvoir annoter plusieurs mthodes est trs pratique.




> Juste une remarque toutefois : vites d'appeler *setAccessible()* dans tous les cas. Il vaudrait mieux le faire seulement en cas de besoin :
> 
> 
> ```
> 
> ```
> 
> En effet *setAccessible()* ncessite certains droits qui ncessitent de signer l'application si elle est dploy par JavaWebStart ou en applet.
> Or si c'est pour appeler une mthode *public* c'est un peu dommage


Ha oui, merci pour l'explication. C'est bon  savoir, ceci dit, je ne compte pas l'utiliser dans le contexte jws ou applet, donc bon ... Mais je le note.




> A ce propos il existe un mcanisme qui permet de contrler cela ds la compilation : APT (Annotation Processing Tool). Grosso modo  la compilation tu peux rechercher les lments annot et les vrifier (avec une API proche de celle de la rflection).


Ha oui, tiens c'est vrai !
a pourrait effectivement tre intressant ... j'ai encore jamais utilis APT, mais pour vrifier la validit de certaines conditions, a pourrait tre pas mal ...


Merci pour ces remarques  ::):

----------


## bobuse

Je dterre cette discussion juste pour dire que j'ai trouv dans la doc de XStream la solution qui vite de faire tout ce que j'ai fait  ::mrgreen::  

http://xstream.codehaus.org/faq.html#Serialization

Voil, il suffit d'ajouter la fonction readResolve dans son objet, et cette mthode sera appele automatiquement aprs dsrialisation.

----------

