Accéder au contenu principal

Utilisation de Spring 3

De très nombreux projets Java J2EE intègrent Spring pour la configuration. Spring est un ensemble de librairies relativement indépendantes qui permettent de gérer différents aspects de la programmation Java. Les plus utilisées sont:
  • l'injection des dépendances (Spring Inversion Of Context ou Dependency Injection)
  • la gestion des transactions
  • la configuration des bases de données (hibernate3)
  • Spring Web
  • Spring Security
  • Spring Batch
  • Spring Roo 
Pour Spring Framework, vous pouvez, soit utiliser la configuration Maven qui récupèrera les classes nécessaires ou télécharger les librairies à l'adresse http://olex.openlogic.com/packages/spring/3.2.4#package_detail_tabs .

Configuration XML pour Spring

Dans ce billet, je vais principalement décrire l'utilisation de l'injection de dépendances, un bien grand mot pour une utilisation courante relativement simple. L'injection de dépendances est un pattern qui permet de définir plusieurs implémentations d'une interface et de définir au moment de l'exécution celle qui l'on souhaite utilisée. L'apport de Spring est que la définition de la classe à utiliser au moment de l'exécution peut être faite dans un fichier XML externe. Il est ainsi possible en choisissant différentes implémentations de complètement redéfinir le fonctionnement d'une application. Cet facilité peut cependant se révéler être un inconvénient dans certains cas. Les principales critiques que l'on peut faire à Spring sont la taille des librairies utilisées (2 Mo pour une application de base) et la taille du fichier XML de configuration qui peut dans certains cas être relativement gros. Les dernières versions de Spring Framework permettent d'utiliser des annotations pour la configuration et permettent ainsi de faire une partie de la configuration en Java. Cela permet de limiter l'utilisation des fichiers XML aux seuls objets qui en ont vraiment besoin, mais peut réduire dans certains cas la flexibilité.

Voici un exemple simple d'utilisation. Je vais définir dans un premier temps une interface.

 public interface ITestSpring {  
      public String getName();  
      public void setName(String name);  
 }  

Je vais maintenant définir une implémentation tout aussi simple. Il s'agit d'une classe Java Bean classique qui implémente l'interface. Définissez également un constructeur par défaut, ce qui permettra à Spring de créer une instance vide et d'utiliser les méthodes "set" pour affecter les valeurs.

public class TestSpringImpl implements ITestSpring {  
      String name;  
   
      public TestSpringImpl() {  
      }  
        
      public TestSpringImpl(String name) {  
           this.name = name;   
      }  
   
      @Override  
      public String getName() {            
           return name;  
      }  
   
      @Override  
      public void setName(String name) {  
           this.name = name;  
      }
 }
   

Définissez un fichier de configuration de la manière suivante. Avec le bouton droit, sélectionnez le menu "New", puis "Spring Bean Configuration File". Indiquez un nom de fichier "simplecontext.xml" par exemple. Vous pourrez ainsi bénéficier du plugin d'Eclipse pour ajouter de données dans le fichier. Vous pouvez également directement manipuler le fichier XML si vous le souhaitez.


Dans l'onglet "Beans", rajoutez les classes que vous souhaitez initialiser (TestSpringImpl dans mon cas).

Vous pouvez ainsi créer une instance de classe et l'initialiser soit en utilisant le constructeur avec les paramètres dans l'ordre de définition ou en utilisant les méthodes "set".


Le fichier XML résultant est le suivant:

 <?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.xsd  
           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
   
   
      <bean class="TestSpringImpl">  
           <constructor-arg value="Test Spring3"></constructor-arg>  
      </bean>  
 </beans>  
   

Rajoutez les librairies suivantes :
  • spring-core-3.2.4.RELEASE.jar
  • spring-beans-3.2.4.RELEASE.jar
  • spring-context-3.2.4.RELEASE.jar
  • spring-expression-3.2.4.RELEASE.jar
  • commons-logging-1.1.1.jar
  • log4j-1.2.15.jar
Et maintenant la classe principale pour tester la configuration.

   
 import org.springframework.context.ApplicationContext;  
 import org.springframework.context.support.FileSystemXmlApplicationContext;  
   
 public class TestSpringMain {  
   
      public static void main(String[] args) {  
        ApplicationContext context = new FileSystemXmlApplicationContext("simplecontext.xml");  
        ITestSpring test = context.getBean(ITestSpring.class);  
        System.out.println("Test = " + test.getName());  
           
        System.exit(0);  
      }   
 }  
   

L'appel à FileSystemXmlApplicationContext permet de charger le fichier XML contenant la configuration initiale. L'appel de "context.getBean(ITestSpring.class)" permet de retrouver la classe correspondante instanciée dans le fichier XML. Dans ce cas, il ne faut pas qu'il y ait d’autre instance de la même classe. En cas d'ambigüité, il est préférable de nommer les instances.

A l'exécution, vous devriez voir :


 Test = Test Spring3  

Annotations avec Spring 3

Spring permet de faire la configuration tout en Java en utilisant des annotations. Il est cependant possible d'utiliser les deux modes de configuration. Les modifications principales sont dans la classe d'implémentation TestSpringImpl, ainsi que dans la classe de configuration.
Dans la classe TestSpringImpl, nous allons simplement rajouter une annotation @Component ainsi que l'import correspondant.

 import org.springframework.stereotype.Component;  
   
 @Component  
 public class TestSpringImpl implements ITestSpring {  
      String name;  
   
      public TestSpringImpl() {  
      }  
        
      public TestSpringImpl(String name) {  
           this.name = name;   
      }  
   
      @Override  
      public String getName() {            
           return name;  
      }  
   
      @Override  
      public void setName(String name) {  
           this.name = name;  
      }
 }  
   

Je vais faire la configuration dans la classe principale. Il est généralement préférable de la faire dans une classe séparée qui ne peut pas être instanciée.

   
 import org.springframework.context.ApplicationContext;  
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;  
 import org.springframework.context.annotation.Bean;  
 import org.springframework.context.annotation.Configuration;  
 import org.springframework.context.support.FileSystemXmlApplicationContext;  
   
 @Configuration  
 public class TestSpringMain {  
   
      @Bean  
      public ITestSpring testSpring() {  
           return new TestSpringImpl("Test Spring with annotations");  
      }  
   
      public static void main(String[] args) {  
        ApplicationContext context1 = new AnnotationConfigApplicationContext(TestSpringMain.class);  
        ITestSpring test1 = (ITestSpring)context1.getBean("testSpring");  
        System.out.println("Test1 = " + test1.getName());  
        System.exit(0);  
      }  
 }  
   

L'annotation @Configuration indique que cette classe va être prise en compte lors de l'appel à AnnotationConfigApplicationContext qui comme son nom l'indique crée un contexte à partir des classes annotées.
L'annotation @Bean indique que la méthode renvoie une instance de la classe. Cette ci est récupérée lors de l'appel à context1.getBean("testSpring"). Il est possible de donner un nom différent en rajoutant un paramètre à l'annotation (ex : @Bean(name=spring1).

Equivalent Java POJO

Spring offre certes une grande flexibilité, mais le surpoids apporté par les librairies nécessaires à son utilisation le limitent aux applications qui nécessitent déjà un grand nombre de librairies. Il est donc préférable de ne l'utiliser que si votre projet pèse déjà 10 Mo ou si cette technologie est déjà utilisée dans votre projet.
L'équivalent standard Java consiste à créer une classe Singleton. En rendant le constructeur non public, le seul moyen de récupérer une instance de cette classe est d'utiliser la commande TestSpringImpl.getInstance().

 public class TestSpringImpl implements ITestSpring {  
      String name;  
        
      static ITestSpring instance = null;  
        
      public static ITestSpring getInstance() {  
           if (instance == null)  
                instance = new TestSpringImpl();  
           return instance;  
      }  
   
      TestSpringImpl() {  
      }  
        
      TestSpringImpl(String name) {  
           this.name = name;   
      }  
   
      @Override  
      public String getName() {            
           return name;  
      }  
   
      @Override  
      public void setName(String name) {  
           this.name = name;  
      }  
   
 }  
   

Si vous souhaitez pouvoir charger les classes dynamiquement, la classe utilitaire suivante peut vous être utile :

 public class ObjectFactory {  
   
   @SuppressWarnings("unchecked")  
      public static Object create(String name) throws Exception {  
     ClassLoader clazzLoader = ObjectFactory.class.getClassLoader();  
     Class clazz;  
     clazz = clazzLoader.loadClass(name);  
     return clazz.newInstance();  
   }  
   
 }  
   

Vous pouvez ainsi charger la classe TestSpringImpl en appelant :

ITestSpring test2 = (ITestSpring)ObjectFactory.create("TestSpringImpl");  
test2.setName("Hello Loaded dynamically");  
System.out.println("Test2 = " + test2.getName());  

Vous avez maintenant le choix. En fonction de la taille de votre projet, vous devrez adapter le choix de la technologie que vous utiliserez.

Commentaires

Posts les plus consultés de ce blog

Supprimer les partitions Raspberry sur une carte SD sous Windows 7 avec Diskpart

Si vous souhaitez récupérer une ancienne carte SD utilisée pour démarrer un Raspberry pour un autre usage (appareil photo, etc), il vous faudra supprimer les deux partitions créées au moment de l'écriture de l'image sur la carte SD. Vous pouvez voir les partition en sélectionnant Menu Windows/Ordinateur/bouton droit "Gérer". Voici un exemple du résultat final. Vous pouvez supprimer la partition Unix de 7 Gb (ou 4Gb en fonction de la taille de votre carte) en sélectionnant la partition puis en faisant "bouton droit Supprimer". Laissez juste une partition pour pouvoir faire les autres manipulations avec DISKPART. Démarrez l'outil DISKPART en ligne de commande. Une nouvelle fenêtre s'ouvrira. Microsoft DiskPart version 6.1.7601 Copyright (C) 1999-2008 Microsoft Corporation. Sur l'ordinateur : FRVILN0H305806 DISKPART> list disk   N° disque  Statut         Taille   Libre    Dyn  GPT   ---------  -------------  -------  -------  ---  ---   D

Comment lire son écran de téléphone Android sur PC (2)

Voici une nouvelle manière d'accéder à votre téléphone depuis votre PC. Cette méthode utilise le câble USB et Google Chrome. Elle fonctionne donc sur Windows, Mac et Linux. Les pré-requis sont les mêmes que ceux du billet précédent : Téléphone configuré en mode Développement Drivers USB installés sur le PC Google Chrome installé L'application Vysor s'installe comme une extension de Google Chrome. Cherchez dans le Webstore et lancez l'installation. Une fois installée, l'application apparaît dans les extensions. Vous pouvez la lancer de différentes manières. La manière la plus simple est d'ouvrir la fenêtre des applications : chrome://apps/ Une autre manière est de créer un raccourci en cliquant sur « Détails ». Ensuite créez un raccourci sur le bureau, le menu démarrer et/ou la barre de tâche. Vous pouvez également cliquer sur afficher dans la boutique et lancer l'application depuis la boutique. Une fois

Serveur d'impression CUPS sur Raspberry Pi

Je possède une très vieille imprimante laser HP Laserjet 6L noir et blanc de 12 ans d'age qui a survécu à plusieurs imprimantes jet d'encre couleurs tombées en désuétude pour obsolescence programmée. J'envisage tout de même sérieusement de les démanteler pour les recycler en CNC, graveur ou autre.   Je continue donc a utiliser cette bonne petite imprimante parallèle qui me rend bien des services (en 12 ans, j'ai changé le toner 3 fois pour un coût de 20 € la cartouche). J'ai donc dû m'équiper d'une adaptateur USB/Parallèle pour pouvoir la connecter sur un PC récent. Le problème principal est que le driver de cette imprimate n'est reconnu que par un seul de mes PC sous Windows 7. Les autres PC sous Windows 8 ou Windows 10 reconnaissent bien l'imprimante, mais sortent des feuilles avec le code Postscript. L'impression depuis une tablette ou un téléphone Androïd est également tout simplement impossible. Pour remédier à ce problème, j'ai don