Un peu plus loin avec Wicket et Spring : Vive l’AOP !
Ceux qui connaissent un peu Spring et l’AOP sauront l’intérêt énorme de cette technique de programmation pourtant encore trop peu connue des développeurs (en tout cas de ceux que je croise).
Je vous propose ici de saupoudrer votre merveilleuse plateforme Eclipse Maven Wicket Spring avec une dose d’AOP histoire de devenir encore un peu plus performants !
L’article qui suit décrit comment ajouter un peu d’AOP sur un projet Wicket.
Pour prendre un exemple concret nous allons ajouter en AOP des traces vers la console rapportant l’utilisation de méthodes d’objets injectés et également leur temps d’exécution, sympa non ?
Pour bien commencer
Pré-requis
Avoir Eclipse (si possible Ganymède pour développeurs JavaEE).
Avoir le plugin Maven m2eclipse installé.
Avoir le plugin Subversion Subclipse installé.
Savoir créer un projet Maven avec l’archetype Wicket (version 1.3.6 pour cet exemple).
Et avoir lu l’article sur le couplage Wicket Spring (ou sur noocodecommit) serait un plus.
Savoir importer un projet SVN sous eclipse également.
Sources de départ
Les sources pour bien commencer sont disponibles sous SVN : http://blog.konkest.com/svn/WicketSpring (non ce n’est pas une erreur et bien les sources d’un précédent article sur lequel nous nous baserons pour la présente démonstration).
Rappel Couplage wicket Spring
1°) Modifier le pom.xml et rajouter d’une part les dépendances Spring :
<dependency> <groupId>org.apache.wicket</groupId> <artifactId>wicket-spring-annot</artifactId> <version>${wicket.version}</version> </dependency> <!-- SPRING DEPENDENCIES --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring</artifactId> <version>${spring.version}</version> </dependency>
2°) et d’autre part la version des dépendances à utiliser :
<properties> <wicket.version>1.3.6</wicket.version> <jetty.version>6.1.4</jetty.version> <spring.version>2.5.4</spring.version> </properties>
3°) Modification du niveau de compilateur en 1.5+ et des project facets en conséquence 5.0+
Pour cela il faut faire un click droit sur le projet puis « propriétés ».
Puis aller sur « Java Compiler » et changer le « Compiler compliance level » (désolé je bosse sous une version anglaise).

Ensuite allez sur « Project Facets » et changez Java de 1.4 à 5.0 au moins, en cliquant sur « Modify project ».
Voici comment se présentent ces écrans :


4°) Ajout de la référence au fichier de configuration Spring dans web.xml
<!-- Déclaration du fichier externe de configuration de Spring --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springConfiguration.xml</param-value> </context-param>
5°) Ajout du fichier springConfiguration.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!-- Indique à Spring de scanner les package pour trouver les annotations en vue de l'injection --> <context:annotation-config/> <context:component-scan base-package="com.konkest"/> <!-- Indique à Spring quelle classe Wicket doit être injectée en tant qu'application --> <bean id="wicketApplication" class="com.konkest.WicketSpring.WicketApplication"> <bean> </beans>
Attention cela ne suffit pas pour cet exemple puisqu’il vous faut ajouter des classes à injecter via Spring…
(cf. les sources SVN et l’article sur le couplage Wicket et Spring.)
Configuration …
Ici j’utilise l’AOP dans le cadre de Spring.
Pas forcément la meilleure utilisation de l’AOP, mais facile et rapide a mettre en oeuvre pour de petits besoins.
Ajout des dépendances Maven pour l’AOP
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency>
Déclaration de l’AOP
Dans le springConfiguration.xml
Ajout des namespaces aop
xmlns:aop="http://www.springframework.org/schema/aop"
et dans la partie schemaLocation :
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
Ajout des déclarations de « jointpoint » et d’ »aspect »
Dans le springConfiguration.xml toujours :
<!-- Debut de la configuration AOP --> <aop:config> <aop:pointcut id="pagePointcut" expression="execution(* com.konkest.faune.*.*(..))"/> <aop:aspect id="testAspect" ref="myTimer"> <aop:before method="pageMethodEntry" pointcut-ref="pagePointcut"/> <aop:after method="pageMethodExit" pointcut-ref="pagePointcut"/> </aop:aspect> </aop:config>
Attention notez bien que je définis le pointcut sur les méthodes des classes du package faune uniquement.
Cela est fait volontairement car Spring ne peut bien évidement travailler en AOP que sur des choses qu’il connait, donc des classes qui lui ont été déclarées comme par exemple Chien et/ou Chat via l’injection de dépendances.
Par ailleurs si vous tentez de mettre :
expression="execution(* com.konkest..*(..))"
(qui défini le pointcut sur l’exécution de toutes les méthodes de toutes les classes du package com.konkest et de ses sous-packages)
Vous constaterez que rien de plus n’apparait dans notre exemple. Forcément Spring ne connait rien d’autre dans le cas présent.
Déclaration du Bean de l’aspect
Dans le springConfiguration.xml encore :
Ajout de la déclaration du bean référencé par pageCallCounter qui contient l’aspect et ses méthodes
<bean id="myTimer" class="com.konkest.aspect.MethodeTimer"/>Notre aspect de test
Pour cet exemple simpliste nous allons juste tracer le temps d’exécution d’une méthode.
Cela montre quand meme l’utilité de l’AOP pour ajouter des traces applicatives après coup, ou pour tenter par exemple de débusquer les point faibles d’une application en termes de performance.
Voici le code de notre aspect de test « MethodeTimer », à placer dans le package « com.konkest.aspect »
package com.konkest.aspect; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint.StaticPart; public class MethodTimer { private long start; private long duration; // Cette méthode est appelée à chaque fois (et avant) qu'une méthode du package défini dans le pointcut est interceptée public void pageMethodEntry(JoinPoint joinPoint) { // Nom de la méthode interceptée String name = joinPoint.getSignature().toLongString(); System.out.println("### Start : " + name); start = System.currentTimeMillis(); } // Cette méthode est appelée à chaque fois (et après) qu'une méthode du package défini dans le pointcut est interceptée public void pageMethodExit(StaticPart staticPart) { duration = System.currentTimeMillis() - start; // Nom de la méthode interceptée String name = staticPart.getSignature().toLongString(); System.out.println("### End of " + name + " after " + duration + " ms."); } }
Test de notre aspect (non ce n’est pas du verlan ^^)
Et bien il faut exécuter notre projet sur le serveur Tomcat… (clique droit sur le Projet, Run As > Run on server)
Et voici si tout va bien le résultat :
Console :

Sources du présent article
Les sources de cet article sont disponibles sous SVN : http://blog.konkest.com/svn/WicketAOPSpring.
Conclusions
Nous venons de voir que nous pouvons aisément utiliser Spring pour faire outre l’injection de dépendance, de la programmation orientée aspect, le tout sur notre application Wicket. Elle est pas belle la vie ?
Seules remarques négatives, à ma connaissance et du fait du mécanisme interne de Spring AOP par création automatique de proxy au chargement, l’utilisation de l’AOP est limitée uniquement sur l’exécution des méthodes des classes injectées. Et également de possibles problèmes de performance (je n’ai jamais utilisé l’AOP suffisamment en profondeur avec Spring ou un autre tisseur d’aspect pour en juger par moi-même).
C’est déjà pas mal mais on peut mieux faire … Affaire à suivre donc, par exemple avec AspectJ et le plugin AspectJDevelopmentTool (AJDT) sous Eclipse.
Ressources
Pour compléter cet article je vous propose de poursuivre la lecture sur les pages suivantes :

juillet 3rd, 2009 at 10 h 10 min
Salut, merci pour la citation et bravo pour ton article !