• CDI : Context Dependency Injection, mise en route (Partie 1)

    Avec l’arrivée de Java 6, la JDK s’équipe enfin de l’injection de dépendance. Cette notion et souplesse introduite par Spring est prête à être utilisée pleinement dans nos applications. Encore faut-il mettre en route la machine par une conf simplissime et choisir l’implémentation de la JSR 299.  Côté implémentation, WELD est l’implémentation de référence, pour la conf un simple fichier bean.xml (même vide) suffira.  Allons-y.


    Commencons par le commencement: Dépendance Maven

    <dependency>
      <groupId>org.jboss.weld.servlet</groupId>
      <artifactId>weld-servlet-core</artifactId>
      <version>2.2.8.Final</version>
    </dependency>
    <dependency>
       <groupId>javax.servlet</groupId>
       <artifactId>javax.servlet-api</artifactId>
       <version>3.0.1</version>
       <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
     

    Classes Java de la couche Service et Buisness

    Ces classes feront une simple opération d’addition entre 2 valeurs.

    package fr.cdi.servlet;
    
    public interface ICalcul {
    	public int addition(int a,int b);
    }
     

    Ci dessous une implémentation de l’interface ICalcul. L’annotation @Default et @Any  est ici facultative car nous avons qu’une seule implémentation possible.  Ces annotations s’appellent un Qualifer.  La spécification de la JSR 299 propose des qualifers par défauts : @Default, @Any, @Named, @New.  Ils permettent à CDI de savoir quelle implémentation injecter. Dans le cas où rien n’est précisé, 2 annotations sont implicitement ajoutées par CDI : @Default et @Any. Comme je vous l’ai dit, dans notre cas nous n’en avons qu’une seule donc aucune ambiguïté à ce niveau. Nous reviendrons plus tard sur ces notions de Qualifier dans un autre billet.  Retenez juste qu’une implémentation injectable aura par défaut 2 types de Qualifer et ce, même si le développeur ne le précise pas : default et any !

    package fr.cdi.servlet;
    import javax.enterprise.inject.Default;
    
    @Default
    @Any
    public class CalculBuisness implements ICalcul {
    
    	public int addition(int a,int b){
    		return a+b;
    	}
    }
     

    Notons la première présence de l’annotation @Inject sur l’attribut de classe. Par cette simple annotation la classe CalculBuisness est automatiquement injectée grâce au qualifier @Default.  L’avantage considérable est ici de découpler le code d’une implémentation particulière. On aurait pu écrire aussi @Inject @Default private ICalcul calculBuisness ou @Inject @Default  @Any private ICalcul calculBuisness.

    package fr.cdi.servlet;
    import javax.inject.Inject;
    
    public class CalculeService {
    
    	@Inject
    	private ICalcul calculBuisness;
    
    	public int addition(String  a,String  b){
    		return calculBuisness.addition(Integer.parseInt(a), Integer.parseInt(b));
    	}
    }
     

    La servlet

    Même principe que précédemment on injecte par annotation la classe CalculeService. L’injection doit se faire de bout en bout c.à.d de la Servlet jusqu’à la dernière classe appelée ( classe buisness).

    package fr.cdi.servlet;
    
    import java.io.IOException;
    import javax.inject.Inject;
    import javax.servlet.GenericServlet;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebServlet;
    
    @WebServlet(value="/addition", name="servletCDI")
    public class ServletCDI extends GenericServlet{
    
    	@Inject
    	private CalculeService calculeService;
    
    	@Override
    	public void service(ServletRequest req, ServletResponse res)
    			throws ServletException, IOException {
    
    		String val1 = req.getParameter("val1");
    		String val2 = req.getParameter("val2");
    		int resultat = calculeService.addition(val1, val2);
    		req.setAttribute("resultat", resultat);
    	req.getRequestDispatcher("/WEB-INF/index.jsp").forward(req, res);
    	}
    }
     

    Le web.xml

    <!DOCTYPE web-app PUBLIC
     "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     "http://java.sun.com/dtd/web-app_2_3.dtd" >
    
    <web-app>
    
      <display-name>Archetype Created Web Application</display-name>
        <resource-env-ref>
        <resource-env-ref-name>BeanManager</resource-env-ref-name>
        <resource-env-ref-type>javax.enterprise.inject.spi.BeanManager</resource-env-ref-type>
      </resource-env-ref>
    </web-app>
     

    Enfin le fameux fichier bean.xml

    Ce fichier est presque vide est doit être au même niveau que le web.xml (WEB-INF). Le bean.xml permet de préciser au serveur web ou application qu’une injection par CDI est à prévoir. Le serveur va donc scanner le projet à le recherche des @Inject. Tous les objets annotés seront instanciés par WELD dans un conteneur dit « léger ». Le fichier bean.xml à d’autre utilité qu’on verra dans un autre billet. Contentons nous du strict minimum pour le moment :-)

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                               http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
           version="1.1" bean-discovery-mode="all">
    </beans>
     

    la JSP

    <%@ taglib uri="http://java.sun.com/jstl/core" prefix="c"%>
    <html>
    <head>
    <body>
    	<h1>Welcome CDI tuto</h1>
    	<c:out value="${resultat}"/>
    
    </body>
    </head>
    </html>
     

    Voici le résultat simple mais efficace.

    CDI_1

     

    L’injection n’est plus l’affaire d’un spécialiste Spring. Elle est belle et bien démocratisée et facile d’utilisation avec la JEE 6. Il serait dommage de s’en priver n’est-ce pas?

    Categories: CDI, Injection, Java, JEE 6

    Comments are currently closed.

    One thought on “CDI : Context Dependency Injection, mise en route (Partie 1)

    • Instances of these classes do not follow the normal rules of what it means to be a CDI-managed bean. Nevertheless, containers support the instantiation, injection, and disposal of such objects just as if they were managed beans.