Package java.lang.reflect
Publié le
Après avoir substantiellement passé en revu le package java.lang, je vais me porter sur java.lang.reflect durant ce post. Comme son nom l’indique, nous retrouvons dans ce package tout l’attirail nécessaire pour jouer avec la reflection. Autrement dit, en ciblant un objet donné, nous pourrons découvrir chacun de ses membres.
A quoi ça sert ?
Concrètement, la reflection trouve son utilité par exemple dans les éditeurs de développement (IDE). Comme l’image ci-dessous le montre, ces outils nous permettent de découvrir la structure d’une classe mais aussi où est-ce qu’elle se trouve dans la hierarchie objet. Ceci souvent au moyen d’un arbre et ce que ce soit en cours de développement mais encore, de manière avantageuse, en cours de débugage.
Il existe d’autres utilisations à la reflection comme par exemple dans les processus de sérialisation, dans l’utilisation d’objets métiers distribués (EJB), les containers web et d’inversion de contrôle etc. Mais dans la pratique comment font donc ces IDE pour nous décrire la structure de nos objets? C’est ce que nous allons découvrir maintenant avec la suite de cet article.
Les classes de bases
En plus des classes se trouvant dans ce package, il nous faudra également
faire appel à une classe étant dans le package java.lang: Class. Je n’en
avais pas encore parlé, voici donc le moment venu… Class représente une
classe (ou une interface) tournant dans la machine virtuelle. Les objets Class
sont créés automatiquement par la JVM au moyen du ClassLoader (faisant
aussi parti du package java.lang) au chargement. Il nous faut en premier lieu
utiliser cette classe avant de pouvoir profiter du contenu de
java.lang.reflect: Class lClazz = Class.forName(className);
Suite à
l’exécution de cette ligne de code nous pouvons être certains qu’un objet
Class correspondant est créé. En effet, le ClassLoader ne va pas charger
toutes les classes de la librairie (ouf!) mais uniquement celles qui sont
utilisées dans l’application.
Comme exemple j’ai créé une petite application1 listant tous les membres d’une classe entrée par l’utilisateur.
champ texte par exemple org.poxd.Reflect ou n’importe quelle classe du JDK
Comme vous pouvez le constater dans les sources après avoir l’objet Class tout est accessible grâce aux classes Constructor, Field, Method et Modifiers de l’API java.lang.reflect. A noter que grâce à la reflection, il est possible de contourner les modificateurs d’accès! Pour davantage d’informations, je vous invite à lire Accès privé… pas tant que ça.
Voilà pour les bases de la reflection. Maintenant un peu plus intéressant, découvrons l’utilisation des Proxy et leur importance au sein d’un certain framework.
Proxy
La classe Proxy offre la possibilité de créer des proxy dynamiques. Autrement dit, elle permet d’ajouter une couche entre un objet target et son créateur. Pourquoi rajouter une couche direz-vous… Eh bien pour le découvrir entrons dans les entrailles du framework Spring2. L’un des modules de Spring permet de faire de la programmation par aspect (AOP pour Aspect Oriented Programming) ce qui offre la possibilité de créer des classes avec une meilleure granularité. Voici par exemple la configuration XML permettant d’afficher un message sur la console avant l’appel de certaines méthodes:
<bean id="kwikEMart"
class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- interface interface implémentée par l'objet _target_ -->
<property name="proxyInterfaces">
<value>org.poxd.store.KwikEMArt</value>
</property>
<property name="interceptorNames">
<list>
<value>welcomeAdvice</value>
</list>
</property>
<property name="target">
<ref="kwikEMartTarget"/>
</property>
</bean> `
Nous n’avons ici qu’une partie du travail à effectuer mais il y a ce qu’il nous faut. Ce bout de code XML permet à Spring de créer un ProxyFactoryBean. Cette classe offre la possibilité d’ajouter des interceptors dans le workflow de votre application. Dans notre cas, le bean correspondant à welcomeAdvice sera appelé (suivant une règle définie ailleurs) par exemple avant l’invocation de la méthode start de notre application pour afficher un message de bienvenue_._
A la base nous avons toujours notre classe ne contenant aucun appel à welcomAdvice. C’est Spring qui va rajouter cet appel avant de poursuivre avec la classe que nous avons développé au départ. Pour ce faire, Spring utilise un Proxy. L’image ci-contre démontre bien le fonctionnement. Avant que le proxy invoke l’objet target il peut faire n’importe quelle opération (dans notre cas appeler welcomeAdvice)! Et de notre côté, l’architecture n’est pas touchée, nos classes ont un focus bien défini.
Voilà en pour ce qui concerne le package java.lang.ref. En attendant que je me penche sur une partie du JDK, les commentaires sont les bienvenus!
-
Vous pouvez retrouver le code source en cliquant ici — code de démo, entrez dans le ↩
-
Pour une description de ce framework, consultez la section About du site www.springframework.org ↩
Ajouter un commentaire