Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
INTRODUCTIONTO CONTEXTS AND
DEPENDENCY INJECTION (CDI)
@antoine_sd
ANTOINE SABOT-DURAND
• Senior Software Engineer @Red Hat
• Java & OSS :
• CDI co-spec lead
• CDI community development
• T...
WHAT IS CDI ?
• Java EE dependency injection standard
• Strong typed and type safe
• Context management
• Observer pattern...
A BIT OF HISTORY
Dec 2009 June 2013 Apr 2014 Sep 2014
CDI
1.0
(Java
EE
6)
CDI
1.1
(Java
EE
7)
CDI
1.2
(1.1
MR)
CDI
2.0
Sta...
IMPLEMENTATIONS
JBoss Weld (Reference Implementation) Apache Open WebBeans
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:
• Al...
THE CDI BEAN
• In Java EE 6 and 7 everything is a Bean including (EJB session beans)
• beans are basic components
• They a...
BASIC DEPENDENCY INJECTION
@Inject
THIS IS A BEAN
public class HelloService {
    public String hello() {
        return "Hello World!";
    }
}
DI IN CONSTRUCTOR
public class MyBean {
    private HelloService service;
    @Inject
    public MyBean(HelloService servi...
DI IN INITIALISER METHOD
public class MyBean {
    private HelloService service;
    @Inject
    public void initService(H...
DI IN FIELD
public class MyBean {
    
@Inject
private HelloService service;
    public void displayHello() {
        disp...
NOTYPE ERASURE IN CDI
public class MyBean {
    @Inject Service<User> userService;
@Inject Service<Staff> staffService;
  ...
NOTYPE ERASURE IN CDI
public class MyBean {
    @Inject Service<User> userService;
@Inject Service<Staff> staffService;
  ...
TYPES OF A BEAN
• A bean will be a candidate for all “injection point” whose type
belongs to its types set
• Bean types se...
TYPES OF A BEAN
public class HelloService {

//Types set : HelloService, Object

}



public class FrenchHelloService exte...
USING QUALIFIERSTO DISTINGUISH
BEANS OFTHE SAMETYPE
TWO SERVICE IMPLEMENTATIONS…
public interface HelloService {
    public String hello();
}
public class FrenchHelloService ...
…NEED QUALIFIERS…
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD, PARAMETER})
public @interface French {}
@Qu...
…TO BE DISTINGUISHED.
@French
public class FrenchHelloService implements HelloService {
    public String hello() {
      ...
QUALIFIED INJECTION POINTS
public class MyBean {
    @Inject @French HelloService service;
    public void displayHello() ...
QUALIFIERS CAN HAVE MEMBERS
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD, PARAMETER})
public @interface Lan...
QUALIFIERS WITH MEMBERS 1/2
@Language(FRENCH)
public class FrenchHelloService implements HelloService {
    public String ...
QUALIFIERS WITH MEMBERS 2/2
public class MyBean {
    @Inject @Language(ENGLISH) HelloService service;
    public void dis...
MULTIPLE QUALIFIERS
public class MyBean {
    @Inject @French
HelloService service;
}
@French @Console @Secured
public cla...
MULTIPLE QUALIFIERS
public class MyBean {
    @Inject @French @Console
HelloService service;
}
@French @Console @Secured
p...
MULTIPLE QUALIFIERS
public class MyBean {
    @Inject @French @Console @Secured
HelloService service;
}
@French @Console @...
MULTIPLE QUALIFIERS
public class MyBean {
    @Inject @French @Console @Secured
HelloService service;
}
@French @Secured
p...
MULTIPLE QUALIFIERS
public class MyBean {
    @Inject @French @Console @Secured
HelloService service;
}
@French @Secured
p...
RESERVED QUALIFIERS
@Default
@Any
@Named
PROGRAMMATIC LOOKUP
SOMETIMES CALLED “LAZY INJECTION”
public class MyBean {
    @Inject Instance<HelloService> service;
    public void displa...
CHECK BEAN EXISTENCE AT RUNTIME
public class MyBean {
    @Inject Instance<HelloService> service;
    public void displayH...
LOOP ON ALL BEANS OF A GIVENTYPE
public class MyBean {
    @Inject @Any Instance<HelloService> services;
    public void d...
SELECT A QUALIFIER AT RUNTIME
public class MyBean {
    @Inject @Any Instance<HelloService> services;
    public void disp...
CONTEXTS
CONTEXTS MANAGE BEANS LIFECYCLE
• They helps container to choose when a bean should be instantiated and destroyed
• They e...
CHOOSINGTHE RIGHT CONTEXT
@SessionScoped
public class CartBean {
    public void addItem(Item item) {
...
    }
}
CHOOSINGTHE RIGHT CONTEXT
@ApplicationScoped
public class CartBean {
    public void addItem(Item item) {
...
    }
}
CHOOSINGTHE RIGHT CONTEXT
@ApplicationScoped
public class CartBean {
    public void addItem(Item item) {
...
    }
}
FAIL...
CONVERSATION IS MANAGE BY DEV
@ConversationScoped
public class CartBean {
    public void addItem(Item item) {
...
    }
}
NEW CONTEXTS CAN BE CREATED
@ThreadScoped
public class CartBean {
    public void addItem(Item item) {
...
    }
}
PRODUCERS
CREATING BEAN FROM ANY CLASS
@Produces
public MyNonCDIClass myProducer() {
return new MyNonCdiClass();
}
...
@Inject
MyNon...
DISPOSER ARE OPTIONAL
@Produces
public MyNonCDIClass myProducer() {
return new MyNonCdiClass();
}
// Will be call at the i...
PRODUCERS MAY HAVE A SCOPE
@Produces
@RequestScoped
public FacesContext produceFacesContext() {
return FacesContext.getCur...
GETTING INFO FROM INJECTION POINT
@Produces
public Logger produceLog(InjectionPoint injectionPoint) {
return Logger.getLog...
REMEMBER :“NOTYPE ERASURE”
@Produces

public <K, V> Map<K, V> produceMap(InjectionPoint ip) {

if (valueIsNumber(ip.getTyp...
EVENTS
A NICE WAYTO ADD DECOUPLING
public class FirstBean {
@Inject Event<Post> postEvent;
public void saveNewPost(Post myPost) {...
EVENTS CAN BE QUALIFIED
public class FirstBean {
@Inject Event<Post> postEvent;
public void saveNewPost(Post myPost) {
pos...
AS ALWAYS “NOTYPE ERASURE”
public class SecondBean {
// these observers will be resolved depending
// on parameter in even...
SOME BUILT-IN EVENTS
public class SecondBean {
public void beginRequest(@Observes @Initialized(RequestScoped.class)
Servle...
DECORATORS & INTERCEPTORS
INTERCEPTORVS DECORATOR
• They are two Aspect Oriented mechanism
• Interceptor is technical oriented : transaction, securi...
DECORATOR
• To use a decorator, your bean should implement an interface
• The decorator will implement the same interface ...
A DECORATOR
@Decorator
@Priority(Interceptor.Priority.APPLICATION)
public abstract class HelloDecorator implements HelloSe...
INTERCEPTOR
Interceptor Binding Annotation
Interceptor Class
+
INTERCEPTOR BINDING…
@InterceptorBinding
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Loggable {}
…IS USEDTO BIND AN INTERCEPTOR
@Interceptor @Loggable
@Priority(Interceptor.Priority.APPLICATION)
public class LogIntercep...
IT CAN BE PUT ON CLASS OR METHOD
@Loggable
public class MyBean {
    @Inject HelloService service;
    public void display...
OTHER FEATURES
• Stereotypes: to create annotation gathering multiple annotations
• Alternatives: to provide alternative t...
THAT’S ALL FOR BASIC CDI
• If you want to learn advanced stuff come to check my over talk : CDI
advanced.
• follow @cdispe...
Upcoming SlideShare
Loading in …5
×

Introduction to CDI

3,291 views

Published on

This presentation provides an introduction to CDI (Contexts and Dependency Injection), covering the basic and intermediate features. It was authored by Antoine Sabot-Durand, the co-spec lead for CDI.

Published in: Technology
  • Be the first to comment

Introduction to CDI

  1. 1. INTRODUCTIONTO 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 Dec 2009 June 2013 Apr 2014 Sep 2014 CDI 1.0 (Java EE 6) CDI 1.1 (Java EE 7) CDI 1.2 (1.1 MR) CDI 2.0 Starts Q1 2016 CDI 2.0 released
  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 Bean including (EJB session beans) • 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 INITIALISER METHOD public class MyBean {     private HelloService service;     @Inject     public void initService(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. NOTYPE ERASURE IN CDI public class MyBean {     @Inject Service<User> userService; @Inject Service<Staff> staffService;      }
  14. 14. NOTYPE ERASURE IN CDI public class MyBean {     @Inject Service<User> userService; @Inject Service<Staff> staffService;      } This works
  15. 15. TYPES OF A BEAN • A bean will be a candidate for all “injection point” whose type belongs to its types set • Bean types set contains its type, all its implementing interfaces and all its ancestors including Object. • Bean types can be restricted by using @Typed annotation (Object is always in the set)
  16. 16. TYPES OF A BEAN public class HelloService {
 //Types set : HelloService, Object
 }
 
 public class FrenchHelloService extends GenericService implements HelloService {
 //Types set : FrenchHelloService, GenericService, HelloService, Object 
 }
 
 @Typed({HelloService.class,GenericService.class})
 public class FrenchHelloService extends GenericService implements HelloService {
 //Types set : GenericService, HelloService, Object 
 }
  17. 17. USING QUALIFIERSTO DISTINGUISH BEANS OFTHE SAMETYPE
  18. 18. TWO 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!";     } }
  19. 19. …NEED QUALIFIERS… @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface French {} @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface English {}
  20. 20. …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!";     } }
  21. 21. 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();     } }
  22. 22. 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     } }
  23. 23. 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!";     } }
  24. 24. 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();     } }
  25. 25. MULTIPLE QUALIFIERS public class MyBean {     @Inject @French HelloService service; } @French @Console @Secured public class FrenchHelloService implements HelloService { }
  26. 26. MULTIPLE QUALIFIERS public class MyBean {     @Inject @French @Console HelloService service; } @French @Console @Secured public class FrenchHelloService implements HelloService { }
  27. 27. MULTIPLE QUALIFIERS public class MyBean {     @Inject @French @Console @Secured HelloService service; } @French @Console @Secured public class FrenchHelloService implements HelloService { }
  28. 28. MULTIPLE QUALIFIERS public class MyBean {     @Inject @French @Console @Secured HelloService service; } @French @Secured public class FrenchHelloService implements HelloService { }
  29. 29. MULTIPLE QUALIFIERS public class MyBean {     @Inject @French @Console @Secured HelloService service; } @French @Secured public class FrenchHelloService implements HelloService { }
  30. 30. RESERVED QUALIFIERS @Default @Any @Named
  31. 31. PROGRAMMATIC LOOKUP
  32. 32. SOMETIMES CALLED “LAZY INJECTION” public class MyBean {     @Inject Instance<HelloService> service;     public void displayHello() {         display( service.get().hello() );     } }
  33. 33. CHECK BEAN EXISTENCE AT RUNTIME public class MyBean {     @Inject Instance<HelloService> service;     public void displayHello() {         if (!service.isUnsatisfied()) {             display( service.get().hello() );         }     } }
  34. 34. LOOP ON ALL BEANS OF A GIVENTYPE public class MyBean {     @Inject @Any Instance<HelloService> services;     public void displayHello() {         for (HelloService service : services) {             display( service.hello() );         }     } }
  35. 35. SELECT A QUALIFIER AT RUNTIME public class MyBean {     @Inject @Any Instance<HelloService> services;     public void displayHello() {         display(             service.select( new AnnotationLiteral()<French> {})                 .get() );     } }
  36. 36. CONTEXTS
  37. 37. 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
  38. 38. CHOOSINGTHE RIGHT CONTEXT @SessionScoped public class CartBean {     public void addItem(Item item) { ...     } }
  39. 39. CHOOSINGTHE RIGHT CONTEXT @ApplicationScoped public class CartBean {     public void addItem(Item item) { ...     } }
  40. 40. CHOOSINGTHE RIGHT CONTEXT @ApplicationScoped public class CartBean {     public void addItem(Item item) { ...     } } FAIL !!!
  41. 41. CONVERSATION IS MANAGE BY DEV @ConversationScoped public class CartBean {     public void addItem(Item item) { ...     } }
  42. 42. NEW CONTEXTS CAN BE CREATED @ThreadScoped public class CartBean {     public void addItem(Item item) { ...     } }
  43. 43. PRODUCERS
  44. 44. CREATING BEAN FROM ANY CLASS @Produces public MyNonCDIClass myProducer() { return new MyNonCdiClass(); } ... @Inject MyNonCDIClass bean;
  45. 45. DISPOSER ARE OPTIONAL @Produces public MyNonCDIClass myProducer() { return new MyNonCdiClass(); } // Will be call at the instance end of life public void releaseMyInstance(@Disposes MyNonCdiClass inst) { inst.clean(); }
  46. 46. PRODUCERS MAY HAVE A SCOPE @Produces @RequestScoped public FacesContext produceFacesContext() { return FacesContext.getCurrentInstance(); }
  47. 47. GETTING INFO FROM INJECTION POINT @Produces public Logger produceLog(InjectionPoint injectionPoint) { return Logger.getLogger(injectionPoint.getMember() .getDeclaringClass().getName()); }
  48. 48. REMEMBER :“NOTYPE 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>();
 }
  49. 49. EVENTS
  50. 50. A NICE WAYTO 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()); } }
  51. 51. 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) {} }
  52. 52. AS ALWAYS “NOTYPE 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) {} }
  53. 53. 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) {} }
  54. 54. DECORATORS & INTERCEPTORS
  55. 55. INTERCEPTORVS DECORATOR • They are two Aspect Oriented mechanism • Interceptor is technical oriented : transaction, security, logging • Interceptor can be bound to any bean or bean method • Decorator is business oriented : change the behaviour of a bean • Decorator is for a given bean class
  56. 56. DECORATOR • To use a decorator, your bean should implement an interface • The decorator will implement the same interface and will be annotated with @Decorator annotation • It can be an abstract class (to avoid choosing methods to decorate) • A decorator injects the bean it decorates with @Delegate annotation
  57. 57. A DECORATOR @Decorator @Priority(Interceptor.Priority.APPLICATION) public abstract class HelloDecorator implements HelloService { // The decorated service may be restricted with qualifiers     @Inject @Delegate HelloService service;     public String hello() {         return service.hello() + "-decorated";     } }
  58. 58. INTERCEPTOR Interceptor Binding Annotation Interceptor Class +
  59. 59. INTERCEPTOR BINDING… @InterceptorBinding @Target({METHOD, TYPE}) @Retention(RUNTIME) public @interface Loggable {}
  60. 60. …IS USEDTO 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());         }     } }
  61. 61. IT CAN BE PUT ON CLASS OR METHOD @Loggable public class MyBean {     @Inject HelloService service;     public void displayHello() {         display( service.hello();     } }
  62. 62. OTHER FEATURES • Stereotypes: to create annotation gathering multiple annotations • Alternatives: to provide alternative to a bean for tests or specific environments • Specialization : to completely override an existing bean • Check the spec on http://cdi-spec.org
  63. 63. THAT’S ALL FOR BASIC CDI • If you want to learn advanced stuff come to check my over talk : CDI advanced. • follow @cdispec and @antoine_sd on twitter • Questions ?

×