1 / 160

Context and Dependency Injection

Context and Dependency Injection. Maxime Lefrançois ( maxime.lefrancois@inria.fr ), M2 MIAGE Casablanca 2012-2013. Introduction. Questions rébarbatives. Pour un objet A ... Combien de clients est-ce que A peut avoir ? est-ce que A est multi- threadé ?

tejano
Télécharger la présentation

Context and Dependency Injection

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Context and Dependency Injection Maxime Lefrançois (maxime.lefrancois@inria.fr), M2 MIAGE Casablanca 2012-2013

  2. Introduction

  3. Questions rébarbatives • Pour un objet A ... • Combien de clients est-ce que A peut avoir ? • est-ce que A est multi-threadé? • Comment j’ai accès à A dans un autre objet B ? • Est-ce que je dois le détruire explicitement ? • Où dois-je garder une référence à A si je ne l’utilise pas ? • Comment définir des implémentations alternatives, pour en changer au moment du déploiement ? • Comment partager cet objet entre d’autres objets ?

  4. Context and Dependency Injection= CDI (JSR-299) • CDI est un modèle riche de programmation couplage faible avec typage fort

  5. CDI • Gestion du cycle de vie des objets avec état, liés à des contextes • injection de dépendanceavec types • intercepteursd’objets et décorateurs • notifications d’évènements • + SPI (pour extensions)

  6. CDI • aboutissement des frameworks java: Seam, Guice, Spring • Au coeur de la plateforme Java EE • mais pas limité à Java EE • implémentation de référence de CDI : Weld(Seam Framework)

  7. Beans – couplage faible • Un objet avec état lié à un contexte = un bean • couplage faible avec typage fort 1. un bean spécifie seulement le type et la sémantique des beans dont il dépend, il ne connait pas: • leur cycle de vie, • leur implémentation concrete • leur modèle de threading

  8. Beans – couplage faible • Un objet avec état lié à un contexte = un bean • couplage faible avec typage fort 2. un bean spécifie seulement le type et la sémantique des beans dont il dépend,leur implémentation, leur cycle de vie, ...peuvent varier en fonction du scénario de déploiement

  9. Beans – couplage faible • Un objet avec état lié à un contexte = un bean • couplage faible avec typage fort 3. Les notifications d’évènement découplent complètement: les producteur d’évènement les consommateurs d’évènements

  10. Beans – couplage faible • Un objet avec état lié à un contexte = un bean • couplage faible avec typage fort 4. Les intercepteurs découplent: les considérations technique la logique métier (programmation par aspect) exemple: sécurité, transactions, ...

  11. Beans – couplage faible • Un objet avec état lié à un contexte = un bean • couplage faible avec typage fort 5. Les décorateurs permettent de compartimenter les logiques métier

  12. Beans – typage fort • Un objet avec état lié à un contexte = un bean • couplage faible avec typage fort 6. le couplage ne se fait pas par des chaînes de caractères, on utilise des annotations: les qualifieurs

  13. Beans – typage fort • Un objet avec état lié à un contexte = un bean • couplage faible avec typage fort 7. l’utilisation du fichier descripteur est limitée pour les informations qui dépendent du déploiement  META-INF/beans.xml

  14. Notion de Bean • Quels beans on connaît ? • C’est quoi un bean ?

  15. Notion de Bean • Quels beans on connaît ? • les JSF Managed Bean: • Un objet géré par un conteneur, avec des restrictions minimes de programmation ~ un POJO (Plain Old Java Object) • Ont des propriétés • Supportent quelques services basiques: • injection de ressources • callbacks de cycle de vie (@PostConstruct, @PreDestroy, ...) • des intercepteurs (définis dans le bean = couplage fort !!!) c’est quoi les propriétés d’un Managed Bean ?

  16. Exercice 1 • Pour commencer, une petite application pour vérifier quelques notions des Servlets et JSF2… • Corrigez les erreurs !

  17. Notion de Bean • Quels beans on connaît ? • les javabeans • les Managed Bean • les EJB Session Beans / Message-drivenBeans • Les beans selon Spring • Les beans selon Seam • ...

  18. Notion de Bean • C’est quoi un bean ? CDI donne une définition claire: • Tout objet qui a un constructeur sans paramètre (ou un constructeur annoté @Inject) (ou un producteur de beans)

  19. Un exemple d’injection Une classe avec une méthode qui découpe un texte en phrases publicclassSentenceParser {public List<String> parse(String text) { ... }} est-ce que c’est un bean ? Un stateless session bean capable de traduire des phrases @StatelesspublicclassSentenceTranslatorimplements Translator {public String translate(String sentence) { ... }} est-ce que c’est un bean ? Son interface locale Translator @Localpublicinterface Translator {public String translate(String sentence);} est-ce que c’est un bean ?

  20. Un exemple d’injection On écrit donc une classe pour traduire un document en entier publicclassTextTranslator {privateSentenceParsersentenceParser;private Translator sentenceTranslator;   @InjectTextTranslator(SentenceParsersentenceParser, Translator sentenceTranslator) {this.sentenceParser = sentenceParser;this.sentenceTranslator = sentenceTranslator;   }public String translate(String text) {StringBuildersb = newStringBuilder();for (String sentence: sentenceParser.parse(text)) {sb.append(sentenceTranslator.translate(sentence));      }returnsb.toString();   }} est-ce que c’est un bean ?

  21. Un exemple d’injection On écrit donc une classe pour traduire un document en entier publicclassTextTranslator {privateSentenceParsersentenceParser;private Translator sentenceTranslator;   @InjectTextTranslator(SentenceParsersentenceParser, Translator sentenceTranslator) {this.sentenceParser = sentenceParser;this.sentenceTranslator = sentenceTranslator;   }public String translate(String text) {StringBuildersb = newStringBuilder();for (String sentence: sentenceParser.parse(text)) {sb.append(sentenceTranslator.translate(sentence));      }returnsb.toString();   }} Les paramètres du constructeur annoté @Inject seront injectés est-ce que c’est un bean ? OUI. Le conteneur va appeler le constructeur annoté @Inject, et injecter d’autres beans dans les paramètres du constructeur.

  22. Un exemple d’injection On écrit donc une classe pour traduire un document en entier publicclassTextTranslator {privateSentenceParsersentenceParser;private Translator sentenceTranslator;   @InjectTextTranslator(SentenceParsersentenceParser, Translator sentenceTranslator) {this.sentenceParser = sentenceParser;this.sentenceTranslator = sentenceTranslator;   }public String translate(String text) {StringBuildersb = newStringBuilder();for (String sentence: sentenceParser.parse(text)) {sb.append(sentenceTranslator.translate(sentence));      }returnsb.toString();   }} On peut maintenant injecter une instance de TextTranslator : Dans un constructeur, une méthode, un attribut d’un bean Ou dans un attribut ou une méthode d’une servlet ou d’un autre composant EJB

  23. Un exemple d’injection Exemple de Managed Bean qui utilise une instance injectée de TextTranslator @Named @RequestScopedpublicclassTranslateController {  @InjectTextTranslatortextTranslator; private String inputText;private String translation;    // JSF action method, perhapspublicvoid translate() {      translation = textTranslator.translate(inputText);    } public String getInputText() {returninputText;   } publicvoidsetInputText(String text) {this.inputText = text;   } public String getTranslation() {return translation;   }}

  24. Utiliser CDI

  25. Dans un projet JEE 6 • Avec Netbeans Cocher la case « utiliser CDI » au moment de la création du projet Java Web ou Java EE • Ça crée simplement un fichier descripteur META-INF/beans.xml • Avec Glassfish: • il suffit d’avoir un fichier descripteur META-INF/beans.xml (même vide !) • Weld, l’implémentation de référencede CDI, est fournie • Avec Tomcat, Jetty, … • Suivre la procédure: http://docs.jboss.org/weld/reference/latest/en-US/html/environments.html#d0e5225

  26. Projet Java SE avec CDI • On utilise l’implémentation de référence: Weld • http://www.seamframework.org/Weld/WeldDistributionDownloads • Le jar: weld-se-core.jar • Ou avec Maven: • Est-ce qu’on doit écrire une classe principale avec un main ? <dependency> • <groupId>org.jboss.weld.se </groupId> • <artifactId>weld-se </artifactId> <version>CHOISIR LA DERNIERE FINALE</version> </dependency>

  27. Projet Java SE avec CDI • Est-ce qu’on doit écrire une classe principale avec un main ? Réponse: NON !!! • Où est l’instance du conteneur de beans ??? • C’est possible de l’instantier nous-même, mais compliqué. • Le plus simple: une méthode main est fournie avec weld-se, • Le point d’entrée de notre application est un écouteur • Écouteur de l’évènement ContainerInitialized • On récupère les paramètres de la ligne de commande par injection @Singletonpublicclass HelloWorld{public void printHello(@Observes ContainerInitialized event,  @Parameters List<String> parameters) {       System.out.println("Hello " + parameters.get(0));   }}

  28. Exercice 2 ² • Quelle différence entre les deux applications 2a, 2b ? • La classe Init: • La bonne façon d’avoir une méthode d’un bean appelée dès que le l’application est déployée (servlets ok, injection ok …) • Le singleton est un singleton EJB ! • A votre avis, pourquoi est-ce que le bean Generator est instantié deux fois? (cf. la console)

  29. Introduction à CDI

  30. Anatomie d’un Bean • Un ensemble non vide de types • Un ensemble non vide de qualifieurs • Un contexte • En option: Un nom EL • Un ensemble de liens de type intercepteurs • Une implémentation • En option: être un bean alternatif

  31. Type, qualifieur et injection de dépendance • On a une référence à un bean par injection de dépendance, un attribut injecté spécifie un « contrat » que le bean injecté doit respecter: • Un ensemble non vide de types • Un ensemble non vide de qualifieurs

  32. Type, qualifieur et injection de dépendance • Ensemble non vide de types: • ex1:publicclass Business  {    ... } • ex2 : publicclassBookShopextends Business  implements Shop<Book> {    ... }

  33. Type, qualifieur et injection de dépendance • Et si on souhaite injecter un objet de type Business ? ambiguité ! Le client doit spécifier un/des qualifieurs • Un qualifieur est une annotation:ex: • Permet de désambiguiser l’objet à injecter, sans utiliser une chaîne de caractères @Qualifier@Retention(RUNTIME)@Target({TYPE, METHOD, PARAMETER, FIELD})public @interfaceCreditCard {}

  34. Type, qualifieur et injection de dépendance • Pour ce point d’injection:@Inject @CreditCardPaymentProcessorpaymentProcessor; • Le conteneur cherche un bean qui satisfait le contrat. • Si il en trouve exactement un, il injecte une instance de ce bean • Sinon, il lance une erreur • exemple de bean qui satisfait le contrat:@CreditCardpublicclassCreditCardPaymentProcessorimplementsPaymentProcessor { ... }

  35. Type, qualifieur et injection de dépendance • Un ensemble non vide de typestoujours au moins le type Object • Un ensemble non vide de qualifieursSi aucun qualifieur n’est spécifié, il y a le qualifieur par défaut: @Default

  36. Exercice 3 • 1- Provoquez une erreur: point d’injection ambigüe, • 2- Provoquez une erreur: point d’injection insatisfiable • 3- Faites en sorte que le nombre affiché soit vraiment aléatoire • A votre avis, pourquoi le nombre ne change pas ? Et le bean generator n’est instantié qu’une seule fois ?

  37. Contexte (scope) • Le contexte d’un bean définit le cycle de vie de ses instances • Un contexte est représenté par une annotation ex: @RequestScoped, @SessionScoped, …

  38. Contexte (scope) • Une instance d’un bean session-scoped est liée à un session d’un utilisateur et est partagé par toutes les requêtes executées dans cette session (on ne peut pas l’enlever, ni le changer) • Un beana un contexte. Si aucun contexte n’est défini, le contexte par défaut est: @Dependent

  39. Nom EL (EL= Expression Language) • Pour référencer un bean et ses propriétés dans une JSF ou une JSP, on associe un nom EL • Annotation @Namedex:public @SessionScoped @Named("cart") classShoppingCartimplementsSerializable { ... public List<Item> getLineItems() {...} ....} • On peutensuitel’utiliserdansune JSF ouune JSP:<h:dataTablevalue="#{cart.lineItems}" var="item">   ...</h:dataTable>

  40. Nom EL (EL= Expression Language) • Pour référencer un bean et ses propriétés dans une JSF ou une JSP, on associe un nom EL • Annotation @Namedex:public @SessionScoped @Named("cart") classShoppingCartimplementsSerializable { ... public List<Item> getLineItems() {...} ....} • On peutensuitel’utiliserdansune JSF ouune JSP:<h:dataTablevalue="#{cart.lineItems}" var="item">   ...</h:dataTable> Propriété lineItems !

  41. Nom EL (EL= Expression Language) • Valeur par défaut: • public @SessionScoped @NamedclassShoppingCartimplementsSerializable { ... public List<Item> getLineItems() {...} ....} • <h:dataTablevalue="#{???.lineItems}" var="item">   ...</h:dataTable> Comme dans Exercice1

  42. Alternatives • Un bean peut être déclaré être une implémentation alternative: • public @Alternative classMockPaymentProcessorextendsPaymentProcessorImpl { ... } • Désactivées par défaut, on peutchoisirune alternative à utiliser au moment du déploiement en le spécifiantdans le descripteur META-INF/beans.xml

  43. Intercepteurs • Existent dans Java EE 5 • import javax.interceptor.AroundInvoke;import javax.interceptor.InvocationContext;public class TracingInterceptor {    @AroundInvoke    public Object logCall(InvocationContextcontext) throws Exception{        System.out.println("Invokingmethod: " + context.getMethod());        return context.proceed();        System.out.println(« Finishedinvokingmethod: " + context.getMethod());    }} • @Interceptors(TracingInterceptor.class, ...)@Statelesspublic class HelloWorldBeanimplementsHelloWorld {     public voidsayHello() {        System.out.println("Hello!");    }}

  44. Intercepteurs • Existent dans Java EE 5, mais contre-intuitif ! • On spécifiait directement la classe de l’intercepteur dans l’EJB ! • On spécifiait directement l’ordre des intercepteurs dans l’EJB !

  45. Intercepteurs • Dans CDI: • annotation de lien à un (groupe d’intercepteurs)@InterceptorBinding@Inherited@Target( { TYPE, METHOD }) @Retention(RUNTIME) public @interfaceTransactional {} 2. L’intercepteur déclare cette annotation:public @Transactional @InterceptorclassTransactionInterceptor { ... } 3. On applique cet aspect à un bean:public @SessionScoped @Transactional classShoppingCartimplementsSerializable { ... } 4. On active les intercepteurs et on définitleurordredans le fichierdescripteur MEAT-INF/beans.xml

  46. Quelles classes sont des beans ? (Injectables, décorables, interceptables, ...) • Les ManagedBeans • Les EJB Session Beans • Les Producer Methods • Les Producer Fields

  47. Les ManagedBeans • Des POJOs gérés par le conteneur, • un petit ensemble de services: • injection de ressource, • callbacks du cycle de vie • intercepteurs • JSR-316 ManagedBeans (22 pages)

  48. Les ManagedBeans • Annotation @ManagedBeanpas nécessaire avec CDI ! • Le conteneur CDI considère chaque classe comme un managedbeans si elle: • n’est pas une classe non-static interne • est une classe concrètes, ou annotées @Decorator • n’est pas un composant EJB (un session bean...) • n’implémente pas javax.enterprise.inject.spi.Extension • a un constructeur approprié : soit • un constructeur sans paramètres • un constructeur annoté @Inject

  49. Les ManagedBeans • Attention, les JPA EntityBeans sont techniquement des ManagedBeans, mais IL NE FAUT PAS INJECTER UN ENTITY BEANIL NE FAUT PAS ASSIGNER UN CONTEXTE AUTRE QUE @Dependent A UN ENTITY BEAN

  50. Les Session Beans • des services avancésproposés par le conteneurd’EJB: • sécurité et gestion des transactions au niveau des méthodes, • gestion des accèsconcurrents, • passivation des instances des stateful session beanset pooling des stateless session beans, • invocation de session beans distantsou de web services, • timers, méthodesasynchrones, • ... • JSR-318 Enterprise JavaBeans Specification (626 pages)

More Related