Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Introduction to cdi given at java one 2014

2.129 visualizaciones

Publicado el

Publicado en: Tecnología
  • Sé el primero en comentar

Introduction to cdi given at java one 2014

  1. 1. INTRODUCTION TO CONTEXTS AND DEPENDENCY INJECTION (CDI) @antoine_sd
  2. 2. ANTOINE SABOT-DURAND • Senior Software Engineer @Red Hat • Java & OSS : • CDI co-spec lead • CDI community development • Tech Lead on Agorava • @antoine_sd
  3. 3. WHAT IS CDI ? • Java EE dependency injection standard • Strong typed and type safe • Context management • Observer pattern included (Event bus) • Highly extensible
  4. 4. A BIT OF HISTORY CDI 1.0 (Java EE 6) CDI 1.1 (Java EE 7) CDI 1.2 (1.1 MR) CDI 2.0 Starts Dec 2009 June 2013 Apr 2014 Sep 2014 CDI 2.0 released Q1 2016
  5. 5. IMPLEMENTATIONS JBoss Weld (Reference Implementation) Apache Open WebBeans
  6. 6. CDI ACTIVATION • In CDI 1.0, you must add a beans.xml file to your archive • Since CDI 1.1, it’s activated by default: • All classes having a “bean defining annotation” become a bean • You can still use beans.xml file to activate CDI explicitly or deactivate it
  7. 7. THE CDI BEAN • In Java EE 6 and 7 everything is a Managed Bean • Managed beans are basic components • They are managed by the container • They all have a lifecycle • They can be intercepted (AOP) • They can be injected • Accessible from outside CDI code.
  8. 8. BASIC DEPENDENCY INJECTION @Inject
  9. 9. THIS IS A BEAN public class HelloService { public String hello() { return "Hello World!"; } }
  10. 10. DI IN CONSTRUCTOR public class MyBean { private HelloService service; @Inject public MyBean(HelloService service) { this.service = service; } }
  11. 11. DI IN SETTER public class MyBean { private HelloService service; @Inject public void setService(HelloService service) { this.service = service; } }
  12. 12. DI IN FIELD public class MyBean { @Inject private HelloService service; public void displayHello() { display(service.hello(); } }
  13. 13. NO TYPE ERASURE IN CDI public class MyBean { @Inject Service<User> userService; @Inject Service<Staff> staffService; } This works
  14. 14. USING QUALIFIERS TO DISTINGUISH BEANS OF THE SAME TYPE
  15. 15. 2 SERVICE IMPLEMENTATIONS… public interface HelloService { public String hello(); } public class FrenchHelloService implements HelloService { public String hello() { return "Bonjour tout le monde!"; } } public class EnglishHelloService implements HelloService { public String hello() { return "Hello World!"; } }
  16. 16. …NEED QUALIFIERS… @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface French {} @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface English {}
  17. 17. …TO BE DISTINGUISHED. @French public class FrenchHelloService implements HelloService { public String hello() { return "Bonjour tout le monde!"; } } @English public class EnglishHelloService implements HelloService { public String hello() { return "Hello World!"; } }
  18. 18. QUALIFIED INJECTION POINTS public class MyBean { @Inject @French HelloService service; public void displayHello() { display( service.hello(); } } public class MyBean { @Inject @English HelloService service; public void displayHello() { display( service.hello(); } }
  19. 19. QUALIFIERS CAN HAVE MEMBERS @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface Language { Languages value(); @Nonbinding String description() default ""; public enum Languages { FRENCH, ENGLISH } }
  20. 20. QUALIFIERS WITH MEMBERS 1/2 @Language(FRENCH) public class FrenchHelloService implements HelloService { public String hello() { return "Bonjour tout le monde!"; } } @Language(ENGLISH) public class EnglishHelloService implements HelloService { public String hello() { return "Hello World!"; } }
  21. 21. QUALIFIERS WITH MEMBERS 2/2 public class MyBean { @Inject @Language(ENGLISH) HelloService service; public void displayHello() { display( service.hello(); } } public class MyBean { @Inject @Language(FRENCH) HelloService service; public void displayHello() { display( service.hello(); } }
  22. 22. MULTIPLE QUALIFIERS public class MyBean { @Inject @French HelloService service; } @French @Console @Secured public class FrenchHelloService implements HelloService { }
  23. 23. MULTIPLE QUALIFIERS public class MyBean { @Inject @French @Console HelloService service; } @French @Console @Secured public class FrenchHelloService implements HelloService { }
  24. 24. MULTIPLE QUALIFIERS public class MyBean { @Inject @French @Console @Secured HelloService service; } @French @Console @Secured public class FrenchHelloService implements HelloService { }
  25. 25. MULTIPLE QUALIFIERS public class MyBean { @Inject @French @Console @Secured HelloService service; } @French @Secured public class FrenchHelloService implements HelloService { }
  26. 26. RESERVED QUALIFIERS @Default @Any @Named
  27. 27. PROGRAMMATIC LOOKUP
  28. 28. SOMETIMES CALLED “LAZY INJECTION” public class MyBean { @Inject Instance<HelloService> service; public void displayHello() { display( service.get().hello() ); } }
  29. 29. CHECK BEAN EXISTENCE AT RUNTIME public class MyBean { @Inject Instance<HelloService> service; public void displayHello() { if (!service.isUnsatisfied()) { display( service.get().hello() ); } } }
  30. 30. INSTANCE<T> IS ITERABLE public interface Instance<T> extends Iterable<T>, Provider<T> { public Instance<T> select(Annotation... qualifiers); public <U extends T> Instance<U> select(Class<U> subtype, Annotation... qualifiers); public <U extends T> Instance<U> select(TypeLiteral<U> subtype, Annotation... qualifiers); public boolean isUnsatisfied(); public boolean isAmbiguous(); public void destroy(T instance); }
  31. 31. LOOP ON ALL BEANS OF A GIVEN TYPE public class MyBean { @Inject @Any Instance<HelloService> services; public void displayHello() { for (HelloService service : services) { display( service.hello() ); } } }
  32. 32. SELECT A QUALIFIER AT RUNTIME public class MyBean { @Inject @Any Instance<HelloService> services; public void displayHello() { display( service.select( new AnnotationLiteral()<French> {}) .get() ); } }
  33. 33. CONTEXTS
  34. 34. CONTEXTS MANAGE BEANS LIFECYCLE • They helps container to choose when a bean should be instantiated and destroyed • They enforce the fact that a given bean is a singleton for a given context • Built-in CDI contexts : • @Dependent (default) • @ApplicationScoped, @SessionScoped, @RequestScoped • @ConversationScoped • @Singleton • You can create your own scope
  35. 35. CHOOSING THE RIGHT CONTEXT @SessionScoped public class CartBean { public void addItem(Item item) { ... } }
  36. 36. CHOOSING THE RIGHT CONTEXT @ApplicationScoped public class CartBean { public void addItem(Item item) { ... } } FAIL !!!
  37. 37. CONVERSATION IS MANAGE BY DEV @ConversationScoped public class CartBean { public void addItem(Item item) { ... } }
  38. 38. NEW CONTEXTS CAN BE CREATED @ThreadScoped public class CartBean { public void addItem(Item item) { ... } }
  39. 39. PRODUCERS
  40. 40. CREATING BEAN FROM ANY CLASS @Produces public MyNonCDIClass myProducer() { return new MyNonCdiClass(); } ... @Inject MyNonCDIClass bean;
  41. 41. PRODUCERS MAY HAVE A SCOPE @Produces @RequestScoped public FacesContext produceFacesContext() { return FacesContext.getCurrentInstance(); }
  42. 42. GETTING INFO FROM INJECTION POINT @Produces public Logger produceLog(InjectionPoint injectionPoint) { return Logger.getLogger(injectionPoint.getMember() .getDeclaringClass().getName()); }
  43. 43. REMEMBER : “NO TYPE ERASURE” @Produces public <K, V> Map<K, V> produceMap(InjectionPoint ip) { if (valueIsNumber(ip.getType())) { return new TreeMap<K, V>(); } return new HashMap<K, V>(); }
  44. 44. EVENTS
  45. 45. A NICE WAY TO ADD DECOUPLING public class FirstBean { @Inject Event<Post> postEvent; public void saveNewPost(Post myPost) { postEvent.fire(myPost); } } public class SecondBean { public void listenPost(@Observes Post post) { System.out.println("Received : " + evt.message()); } }
  46. 46. EVENTS CAN BE QUALIFIED public class FirstBean { @Inject Event<Post> postEvent; public void saveNewPost(Post myPost) { postEvent.select( new AnnotationLiteral()<French> {}).fire(myPost); } } public class SecondBean { // these 3 observers will be called public void listenFrPost(@Observes @French Post post) {} public void listenPost(@Observes Post post) {} public void listenObject(@Observes Object obj) {} // This one won’t be called public void listenEnPost(@Observes @English Post post) {} }
  47. 47. AS ALWAYS “NO TYPE ERASURE” public class SecondBean { // these observers will be resolved depending // on parameter in event payload type public void listenStrPost(@Observes Post<String> post) {} public void listenNumPost(@Observes Post<Number> post) {} }
  48. 48. SOME BUILT-IN EVENTS public class SecondBean { public void beginRequest(@Observes @Initialized(RequestScoped.class) ServletRequest req) {} public void endRequest(@Observes @Destroyed(RequestScoped.class) ServletRequest req) {} public void beginSession(@Observes @Initialized(SessionScoped.class) HttpSession session) {} public void endSession(@Observes @Destroyed(SessionScoped.class) HttpSession session) {} }
  49. 49. DECORATORS & INTERCEPTORS
  50. 50. A DECORATOR @Decorator @Priority(Interceptor.Priority.APPLICATION) public class HelloDecorator implements HelloService { // The decorated service may be restricted with qualifiers @Inject @Delegate HelloService service; public String hello() { return service.hello() + "-decorated"; } }
  51. 51. INTERCEPTOR BINDING… @InterceptorBinding @Target({METHOD, TYPE}) @Retention(RUNTIME) public @interface Loggable {}
  52. 52. …IS USED TO BIND AN INTERCEPTOR @Interceptor @Loggable @Priority(Interceptor.Priority.APPLICATION) public class LogInterceptor { @AroundInvoke public Object log(InvocationContext ic) throws Exception { System.out.println("Entering " + ic.getMethod().getName()); try { return ic.proceed(); } finally { System.out.println("Exiting " + ic.getMethod().getName()); } } }
  53. 53. IT CAN BE PUT ON CLASS OR METHOD @Loggable public class MyBean { @Inject HelloService service; public void displayHello() { display( service.hello(); } }
  54. 54. THAT’S ALL FOR BASIC CDI • If you want to learn advanced stuff come to : Going Farther with CDI 1.2 [CON5585] Monday 5:30pm • visit : http://cdi-spec.org • follow @cdispec and @antoine_sd on twitter • Questions ?

×