Cet article va vous présenter les quelques étapes nécessaires pour coupler Wicket avec Spring, histoire de bénéficier par exemple de l’injection de dépendances.

Pré-requis

Si vous avez tout suivi à la lettre, et que vous lancez l’application sur un serveur (Click droit sur le projet, Run As > Run on Server), vous devriez voir la page suivante dans un navigateur :

L’ajout de Spring

Ajout des dépendances dans Maven

Dans un premier temps nous allons ajouter une dépendance pour permettre l’intégration de Wicket et Spring.

Pour cela, dans le fichier pom.xml ajouter la dépendance suivante :

<dependency>
    <groupId>org.apache.wicket</groupId>
    <artifactId>wicket-spring-annot</artifactId>
    <version>${wicket.version}</version>
</dependency>

Si vous avez suivi le QuickStart sur Wicket et Maven vous devriez avoir la variable wicket.version définie en bas de fichier. Sinon pensez à la déclarer …

Ensuite il faut ajouter la déclaration de dépendance du package principal de Spring (pas l’unique mais ici ce sera suffisant).

<!--  SPRING DEPENDENCIES -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring</artifactId>
    <version>${spring.version}</version>
</dependency>

La encore vous remarquerez l’utilisation d’une variable « spring.version » qu’il faut déclarer en fin de fichier en ajoutant par exemple :

<properties>
    <wicket.version>1.3.5</wicket.version>
    <jetty.version>6.1.4</jetty.version>
    <spring.version>2.5.4</spring.version>
 </properties>

Préparer l’application pour l’utilisation de Spring

Il faut modifier ensuite votre application Wicket pour y ajouter d’une part une méthode de récupération du contexte comme suit :

/**
 * Récupération du contexte applicatif
 * @return ApplicationContext
 */
public final ApplicationContext context() {
    return WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext() );
}

Puis ensuite toujours dans votre application modifier la méthode init() pour ajouter un écouteur d’instanciation de composant utilisant l’injection de dépendance de Spring.

protected void init() {
    super.init();
    // Permettre l'injection de dépendances par Spring
    addComponentInstantiationListener( new SpringComponentInjector( this, context() ) );
}

Pour vous éviter les galères si votre IDE negère pas la recherche automatique d’imports, voici donc les imports nécessaires :

import org.apache.wicket.spring.injection.annot.SpringComponentInjector;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

A ce stade si votre projet est en build automatique et que votre serveur détecte les changements et se relance, il y aura des erreurs car nous n’avons pas configuré Spring et son contexte applicatif.

Ajout d’un fichier de configuration pour Spring

Il faut modifier le fichier Web.xml et ajouter la déclaration du fichier de paramétrage spécifique de Spring, en début de fichier, après le display-name idéalement, de la façon suivante :

<!-- 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>

Il faut également rajouter la déclaration de listener suivant en fin de fichier web.xml, pour permettre l’utilisation de beans de portée request, session, global session. Attention le code qui suit est valable pour les conteneurs de servlets 2.4 et supèrieurs. (pour plus de détails sur la configuration Spring se reporter à la Documentation Spring – lien dans les ressources en bas de cet article).

<!-- Declaration du Listener de chargement de contexte de Spring -->
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Puis bien évidement il faut créer le fichier en question et le placer idéalement dans le répertoire src/main/resources.

Voici le contenu minimum du fichier :

<?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 quelle classe Wicket doit être injectée en tant qu'application -->
	<bean id="wicketApplication" class="com.konkest.WicketSpring.WicketApplication">
	</bean>
</beans>

Pensez à remplacer « com.konkest.WicketSpring.WicketApplication » par le path complet de votre application package+classe.

A ce stade votre projet doit compiler et se lancer sur le serveur sans changement notable.

(Tout cela c’est bien beau mais si on en fait rien ça n’a pas d’intérêt.)

Testons un peu le couplage Spring/Wicket

Nous allons tester l’une des fonctionnalités la plus utilisée de Spring :  l’injection de dépendances.

Pour cela je vous propose de créer un exemple idiot constitué de :

  • une interface IAnimal proposant une méthode :
    • public String crier();
      public interface IAnimal {
          public String crier();
      }
  • Et deux classes l’implémentant :
    • Chien qui retourne « Ouaf ouaf »
    • Chat qui retourne « Miaou miaou »
import org.springframework.stereotype.Component;
@Component( "chien" )
public class Chien implements IAnimal {
    public String crier() {
	return "ouaf ouaf";
    }
}

et

import org.springframework.stereotype.Component;
@Component("chat")
public class Chat implements IAnimal{
    public String crier() {
	return "miaou miaou";
    }
}

Et bien évidement nous allons utiliser tout cela dans notre HomePage Wicket en ne manipulant que l’interface, et injecter l’implémentation via Spring.

Injection par annotations

Première chose à faire pour permettre l’utilisation des annotations, il faut configurer votre projet Eclipse pour les supporter. Pour cela deux choses à faire :

  • Ajouter une compatibilité java 5.0 (Click droit sur le projet, puis Properties et Java Compiler, changer alors le compiler compliance level sur 5.0)

20090523_03_ChangeCompilerLevel

  • Changer le niveau de project facets (toujours dans les propriétés du projet, choisir Project Facets et vérifier que la version pour Java est à 5.0)

20090523_02_ChangeProjectFacet

Maintenant nous allons rajouter la déclaration de l’interface IAnimal dans la HomePage :

@SpringBean( name = "chien" )
private IAnimal animal;

Il faut alors importer :

import org.apache.wicket.spring.injection.annot.SpringBean;

ainsi que IAnimal si elle n’est pas dans le package de la HomePage.

import com.konkest.faune.IAnimal;

Puis pour le besoin du test on va appeler la méthode crier de l’interface IAnimal :

add(new Label("message", "Mon animal fait : " + animal.crier()));

en remplaçant le précédent Label généré automatiquement lors de la création du projet.

A ce stade le code compile et le serveur se lance mais l’application provoque une Unexpected Runtime Exception lorsque l’on y accède. En effet nous n’avons pas dit à Spring qu’il devait scanner les packages pour trouver les annotations et s’en servir pour l’injection des dépendances.

Dernière étape donc : indiquer à Spring qu’il doit scanner les packages et utiliser les annotations pour l’injection. Pour cela il faut modifier le fichier de configuration de Spring dans notre projet : springConfiguration.xml, et ne pas oublier de modifier les déclarations de namespaces.

<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">
	<context:annotation-config/>
	<context:component-scan base-package="com.konkest.WicketSpring"/>

Et voilà il n’y a plus qu’a tester en lançant votre serveur… si tout va bien « ouaf ouaf » devrait apparaitre…

20090523_04_ouaf

Changez donc l’annotation en :

@SpringBean( name = "chat" )
private IAnimal animal;

et relancez … « miaou miaou » …

20090523_05_miaou

C’est un peu bof comme exemple mais ça prouve que l’injection via Spring fonctionne
:) Félicitations ! et merci pour la patience d’avoir suivi jusque là.

Prochaine étape Ajouter Hibernate … A suivre …


Sources disponibles sous SVN

Se connecter au repository suivant : http://blog.konkest.com/svn/WicketSpring .


Ressources utilisées pour cet article: