introduction to cdi given at java one 2014

54
INTRODUCTION TO CONTEXTS AND DEPENDENCY INJECTION (CDI) @antoine_sd

Upload: antoine-sabot-durand

Post on 27-Nov-2014

745 views

Category:

Technology


1 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Introduction to cdi given at java one 2014

INTRODUCTION TO CONTEXTS AND DEPENDENCY INJECTION (CDI)

@antoine_sd

Page 2: Introduction to cdi given at java one 2014

ANTOINE SABOT-DURAND

• Senior Software Engineer @Red Hat

• Java & OSS :

• CDI co-spec lead

• CDI community development

• Tech Lead on Agorava

• @antoine_sd

Page 3: Introduction to cdi given at java one 2014

WHAT IS CDI ?

• Java EE dependency injection standard• Strong typed and type safe• Context management• Observer pattern included (Event bus)• Highly extensible

Page 4: Introduction to cdi given at java one 2014

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 M

R)

CDI 2.0 Starts

Q1 2016

CDI 2.0 released

Page 5: Introduction to cdi given at java one 2014

IMPLEMENTATIONSJBoss Weld (Reference Implementation) Apache Open WebBeans

Page 6: Introduction to cdi given at java one 2014

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

Page 7: Introduction to cdi given at java one 2014

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.

Page 8: Introduction to cdi given at java one 2014

BASIC DEPENDENCY INJECTION

@Inject

Page 9: Introduction to cdi given at java one 2014

THIS IS A BEAN

public class HelloService {    public String hello() {        return "Hello World!";    }}

Page 10: Introduction to cdi given at java one 2014

DI IN CONSTRUCTORpublic class MyBean {

    private HelloService service;

    @Inject    public MyBean(HelloService service) {        this.service = service;    }}

Page 11: Introduction to cdi given at java one 2014

DI IN SETTERpublic class MyBean {

    private HelloService service;

    @Inject    public void setService(HelloService service) {        this.service = service;    }}

Page 12: Introduction to cdi given at java one 2014

DI IN FIELDpublic class MyBean {     @Inject private HelloService service;

    public void displayHello() {        display(service.hello();    }}

Page 13: Introduction to cdi given at java one 2014

NO TYPE ERASURE IN CDI

public class MyBean {

    @Inject Service<User> userService;

@Inject Service<Staff> staffService;    }

This w

orks

Page 14: Introduction to cdi given at java one 2014

USING QUALIFIERS TO DISTINGUISH BEANS OF THE SAME TYPE

Page 15: Introduction to cdi given at java one 2014

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!";    }}

Page 16: Introduction to cdi given at java one 2014

…NEED QUALIFIERS…@Qualifier@Retention(RUNTIME)@Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface French {}

@Qualifier@Retention(RUNTIME)@Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface English {}

Page 17: Introduction to cdi given at java one 2014

…TO BE DISTINGUISHED.

@Frenchpublic class FrenchHelloService implements HelloService {    public String hello() {        return "Bonjour tout le monde!";    }}

@Englishpublic class EnglishHelloService implements HelloService {    public String hello() {        return "Hello World!";    }}

Page 18: Introduction to cdi given at java one 2014

QUALIFIED INJECTION POINTSpublic 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();    }}

Page 19: Introduction to cdi given at java one 2014

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    }}

Page 20: Introduction to cdi given at java one 2014

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!";    }}

Page 21: Introduction to cdi given at java one 2014

QUALIFIERS WITH MEMBERS 2/2public 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();    }}

Page 22: Introduction to cdi given at java one 2014

MULTIPLE QUALIFIERS

public class MyBean {    @Inject @French HelloService service;}

@French @Console @Securedpublic class FrenchHelloService implements HelloService {

}

Page 23: Introduction to cdi given at java one 2014

MULTIPLE QUALIFIERS

public class MyBean {    @Inject @French @Console HelloService service;}

@French @Console @Securedpublic class FrenchHelloService implements HelloService {

}

Page 24: Introduction to cdi given at java one 2014

MULTIPLE QUALIFIERS

public class MyBean {    @Inject @French @Console @Secured HelloService service;}

@French @Console @Securedpublic class FrenchHelloService implements HelloService {

}

Page 25: Introduction to cdi given at java one 2014

MULTIPLE QUALIFIERS

public class MyBean {    @Inject @French @Console @Secured HelloService service;}

@French @Securedpublic class FrenchHelloService implements HelloService {

}

Page 26: Introduction to cdi given at java one 2014

RESERVED QUALIFIERS

@Default@Any@Named

Page 27: Introduction to cdi given at java one 2014

PROGRAMMATIC LOOKUP

Page 28: Introduction to cdi given at java one 2014

SOMETIMES CALLED “LAZY INJECTION”

public class MyBean {

    @Inject Instance<HelloService> service;

    public void displayHello() {        display( service.get().hello() );    }}

Page 29: Introduction to cdi given at java one 2014

CHECK BEAN EXISTENCE AT RUNTIMEpublic class MyBean {

    @Inject Instance<HelloService> service;

    public void displayHello() {        if (!service.isUnsatisfied()) {            display( service.get().hello() );        }    }}

Page 30: Introduction to cdi given at java one 2014

INSTANCE<T> IS ITERABLEpublic 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);}

Page 31: Introduction to cdi given at java one 2014

LOOP ON ALL BEANS OF A GIVEN TYPEpublic class MyBean {

    @Inject @Any Instance<HelloService> services;

    public void displayHello() {        for (HelloService service : services) {            display( service.hello() );        }    }}

Page 32: Introduction to cdi given at java one 2014

SELECT A QUALIFIER AT RUNTIMEpublic class MyBean {

    @Inject @Any Instance<HelloService> services;

    public void displayHello() {        display(             service.select( new AnnotationLiteral()<French> {})                .get() );    }}

Page 33: Introduction to cdi given at java one 2014

CONTEXTS

Page 34: Introduction to cdi given at java one 2014

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

Page 35: Introduction to cdi given at java one 2014

CHOOSING THE RIGHT CONTEXT

@SessionScopedpublic class CartBean {

    public void addItem(Item item) { ...    } }

Page 36: Introduction to cdi given at java one 2014

CHOOSING THE RIGHT CONTEXT

@ApplicationScopedpublic class CartBean {

    public void addItem(Item item) { ...    } } FAI

L !!!

Page 37: Introduction to cdi given at java one 2014

CONVERSATION IS MANAGE BY DEV

@ConversationScopedpublic class CartBean {

    public void addItem(Item item) { ...    } }

Page 38: Introduction to cdi given at java one 2014

NEW CONTEXTS CAN BE CREATED

@ThreadScopedpublic class CartBean {

    public void addItem(Item item) { ...    } }

Page 39: Introduction to cdi given at java one 2014

PRODUCERS

Page 40: Introduction to cdi given at java one 2014

CREATING BEAN FROM ANY CLASS

@Producespublic MyNonCDIClass myProducer() {return new MyNonCdiClass();}...@InjectMyNonCDIClass bean;

Page 41: Introduction to cdi given at java one 2014

PRODUCERS MAY HAVE A SCOPE

@Produces@RequestScopedpublic FacesContext produceFacesContext() { return FacesContext.getCurrentInstance();}

Page 42: Introduction to cdi given at java one 2014

GETTING INFO FROM INJECTION POINT

@Producespublic Logger produceLog(InjectionPoint injectionPoint) { return Logger.getLogger(injectionPoint.getMember() .getDeclaringClass().getName());}

Page 43: Introduction to cdi given at java one 2014

REMEMBER : “NO TYPE ERASURE”

@Producespublic <K, V> Map<K, V> produceMap(InjectionPoint ip) { if (valueIsNumber(ip.getType())) { return new TreeMap<K, V>(); } return new HashMap<K, V>();}

Page 44: Introduction to cdi given at java one 2014

EVENTS

Page 45: Introduction to cdi given at java one 2014

A NICE WAY TO ADD DECOUPLINGpublic 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()); }}

Page 46: Introduction to cdi given at java one 2014

EVENTS CAN BE QUALIFIEDpublic 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) {}}

Page 47: Introduction to cdi given at java one 2014

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) {}}

Page 48: Introduction to cdi given at java one 2014

SOME BUILT-IN EVENTSpublic 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) {}}

Page 49: Introduction to cdi given at java one 2014

DECORATORS & INTERCEPTORS

Page 50: Introduction to cdi given at java one 2014

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";    }}

Page 51: Introduction to cdi given at java one 2014

INTERCEPTOR BINDING…

@InterceptorBinding@Target({METHOD, TYPE}) @Retention(RUNTIME)public @interface Loggable {}

Page 52: Introduction to cdi given at java one 2014

…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());        }    } }

Page 53: Introduction to cdi given at java one 2014

IT CAN BE PUT ON CLASS OR METHOD

@Loggablepublic class MyBean {

    @Inject HelloService service;

    public void displayHello() {        display( service.hello();    }}

Page 54: Introduction to cdi given at java one 2014

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 ?