Upgrade to Pro — share decks privately, control downloads, hide ads and more …

CDI 2.0

Mark Paluch
September 07, 2017

CDI 2.0

Contexts and Dependency Injection has become an integral part of Java to leverage dependency injection and bean management aside of EJB. The current CDI 1.2 is widely used amongst Java Enterprise 7 applications. The Expert Group formed in Fall 2014 to work on the next version of the specification and released the CDI 2.0 spec in early 2017, which will be part of Java Enterprise 8.

Links:
* Code: https://github.com/mp911de/cdi-2.0

Mark Paluch

September 07, 2017
Tweet

More Decks by Mark Paluch

Other Decks in Programming

Transcript

  1. What's New in CDI 2.0
    JSR 365 Mark Paluch • @mp911de

    View Slide

  2. CDI Timeline
    Dec 2009
    CDI 1.0
    (Java
    EE
    6)
    Jun 2013
    CDI 1.1 (Java
    EE
    7)
    Apr 2014
    CDI 1.2
    (M
    R)
    Sep 2014
    CDI 2.0
    (Kickoff)
    May 2017
    CDI 2.0
    (Release)
    Sept 2017?
    Java
    EE
    8

    View Slide

  3. CanDI

    View Slide

  4. Community Survey
    1. Asynchronous method invocation
    2. Add asynchronous event support
    3. @Startup for CDI
    4. Bootstrapping the container
    outside Java EE
    5. AOP for produced or custom
    beans

    6. Mutable container at runtime
    7. Security support
    8. Observers ordering
    9. Enhance SPI to give better access
    to all metadata
    10. Better EAR support
    Source: https://jcp.org/aboutJava/communityprocess/ec-public/materials/2015-06-1516/JSR-365-Review.pdf

    View Slide

  5. @ApplicationScoped
    class UserService {
    User createUser() {
    return …;
    }
    }
    class UserServlet extends HttpServlet {
    @Inject
    UserService service;
    }

    View Slide

  6. @ApplicationScoped
    class UserService {
    void onUserCreated(@Observes UserEvent event) {
    }
    }
    class UserServlet extends HttpServlet {
    @Inject
    UserService service;
    }
    class UserServiceFactory {
    @Produces
    @ApplicationScoped
    UserService createService() {
    return new UserService();
    }
    }

    View Slide

  7. Road towards JavaEE 8
    • Java 8 baseline
    • Spec split: Core/SE/EE
    CDI Specification
    CDI Core
    CDI for
    Java SE
    CDI for
    Java EE

    View Slide

  8. Java SE

    View Slide

  9. Java SE
    • Currently: Implementation-specific in Weld/
    OpenWebBean
    • Spec Goal: Bootstrap API

    View Slide

  10. SeContainerInitializer initializer = SeContainerInitializer
    .newInstance()

    .disableDiscovery()

    .addBeanClasses(MyApp.class)

    .addPackages(MyOtherServices.class)

    .addExtensions(MyExtension.class);


    try (SeContainer container = initializer.initialize()) {


    MyApp service = container.select(MyService.class).get();

    service.runMyApplication();

    }

    View Slide

  11. SeContainerInitializer initializer = SeContainerInitializer
    .newInstance()

    .disableDiscovery()

    .addBeanClasses(MyApp.class)

    .addPackages(MyOtherServices.class)

    .addExtensions(MyExtension.class);


    try (SeContainer container = initializer.initialize()) {


    MyApp service = container.select(MyService.class).get();

    service.runMyApplication();

    }

    View Slide

  12. SeContainerInitializer initializer = SeContainerInitializer
    .newInstance()

    .disableDiscovery()

    .addBeanClasses(MyApp.class)

    .addPackages(MyOtherServices.class)

    .addExtensions(MyExtension.class);


    try (SeContainer container = initializer.initialize()) {


    MyApp service = container.select(MyService.class).get();

    service.runMyApplication();

    }

    View Slide

  13. Events

    View Slide

  14. @Observes

    View Slide

  15. @Priority

    View Slide

  16. Ordered Events
    • Add @Priority to event observers
    • Aids observer ordering
    • Total global order determined when the event is fired

    View Slide

  17. Observer Ordering
    public void observer(@Observes @Priority(2500) MyEvent event) {

    System.out.println("Default priority");

    }

    View Slide

  18. public void earlier(@Observes @Priority(2499) MyEvent event) {

    // yay! I'm first

    System.out.println("Notified before all other observers");

    }

    public void observer(@Observes MyEvent event) {

    System.out.println("Default priority");

    }
    public void later(@Observes @Priority(2501) MyEvent event) {

    System.out.println("Notified after all other observers");

    }

    View Slide

  19. public void earlier(@Observes @Priority(2499) MyEvent event) {

    // yay! I'm first

    System.out.println("Notified before all other observers");

    }

    public void observer(@Observes MyEvent event) {

    System.out.println("Default priority");

    }
    public void later(@Observes @Priority(2501) MyEvent event) {

    System.out.println("Notified after all other observers");

    }

    View Slide

  20. public void earlier(@Observes @Priority(2499) MyEvent event) {

    // yay! I'm first

    System.out.println("Notified before all other observers");

    }

    public void observer(@Observes MyEvent event) {

    System.out.println("Default priority");

    }
    public void later(@Observes @Priority(2501) MyEvent event) {

    System.out.println("Notified after all other observers");

    }

    View Slide

  21. public void earlier(@Observes @Priority(2499) MyEvent event) {

    // yay! I'm first

    System.out.println("Notified before all other observers");

    }

    public void observer(@Observes MyEvent event) {

    System.out.println("Default priority");

    }
    public void later(@Observes @Priority(2501) MyEvent event) {

    System.out.println("Notified after all other observers");

    }

    View Slide

  22. @ObservesAsync

    View Slide

  23. Asynchronous Events
    • Notify event observers asynchronously
    • One or more different threads
    • Decoupled from synchronous events

    View Slide

  24. Firing Async Events
    @Inject

    private Event event;

    public void triggerEvent() {

    event.fireAsync(new MyEventPayload());

    }

    View Slide

  25. Firing Async Events
    @Inject

    private Event event;

    public void triggerEvent() {

    event.fireAsync(new MyEventPayload());

    }

    View Slide

  26. Observing Async Events
    public void observer(@ObservesAsync MyEvent payload) {

    System.out.println("Yay, I'm called async!");

    }

    View Slide

  27. How it works
    @Observes @ObservesAsync
    event.fire(…)
    Sync call Not notified
    event.fireAsync(…)
    Not notified Async call

    View Slide

  28. Asynchronous Events
    • Exceptions and Synchronization with
    CompletionStage
    • Active scopes: Request, Application
    • Custom scopes depend on the implementation

    View Slide

  29. Portable Extensions

    View Slide

  30. Meta-Data Builder API
    • Standardized API
    • CDI 1.0+: Very verbose to create
    • AnnotatedTypes, Beans, BeanAttributes, InjectionPoints, and
    ObserverMethods
    • Builder and Configurator-style

    View Slide

  31. class AfterBeanDiscoveryExtension implements Extension {

    void afterBeanDiscovery(
    @Observes AfterBeanDiscovery event) {

    event.addBean()
    .types(MyService.class)
    .scope(RequestScoped.class)
    .createWith(ctx -> …)
    .name("myservice");
    }
    }
    Add a Bean

    View Slide

  32. class AfterBeanDiscoveryExtension implements Extension {

    void afterBeanDiscovery(
    @Observes AfterBeanDiscovery event) {

    event.addBean()
    .types(MyService.class)
    .scope(RequestScoped.class)
    .createWith(ctx -> …)
    .name("myservice");
    }
    }
    Add a Bean

    View Slide

  33. class ProcessAnnotatedTypeExtension implements Extension {

    void processAnnotatedType(@Observes
    @WithAnnotations(UseCase.class) ProcessAnnotatedType pat) {


    pat.configureAnnotatedType()
    .methods() 

    .forEach(m -> m.add(CacheableLiteral.INSTANCE));

    }
    }
    Add annotation to Methods

    View Slide

  34. class ProcessAnnotatedTypeExtension implements Extension {

    void processAnnotatedType(@Observes
    @WithAnnotations(UseCase.class) ProcessAnnotatedType pat) {


    pat.configureAnnotatedType()
    .methods() 

    .forEach(m -> m.add(CacheableLiteral.INSTANCE));

    }
    }
    Add annotation to Methods

    View Slide

  35. AOP on produced Bean
    • CDI 1.0+: Interceptor applied to producer method
    • CDI 2.0: InterceptionFactory
    @Produces 

    @Transactional

    public MyService produceService() {

    ... 

    }

    View Slide

  36. AOP on produced Bean
    @Produces

    @RequestScoped

    public MyService createTransactional(InterceptionFactory ify) {


    ify.configure()

    .filterMethods(m -> m.getJavaMember().getName().equals("save"))

    .forEach(m -> m.add(new AnnotationLiteral() {}));


    return ify.createInterceptionProxy(new MyService());

    }

    View Slide

  37. AOP on produced Bean
    @Produces

    @RequestScoped

    public MyService createTransactional(InterceptionFactory ify) {


    ify.configure()

    .filterMethods(m -> m.getJavaMember().getName().equals("save"))

    .forEach(m -> m.add(new AnnotationLiteral() {}));


    return ify.createInterceptionProxy(new MyService());

    }

    View Slide

  38. Proxy matters

    View Slide

  39. Proxy injection
    @Inject

    private MyService myService;
    This is a proxy instance

    View Slide

  40. Proxy injection
    @Inject
    @Named("myBean")

    private ConcurrentHashMap myService;
    /** Implementation for put and putIfAbsent */

    final V putVal(K key, V value, boolean onlyIfAbsent)

    View Slide

  41. Normal-scoped beans
    • Must be proxyable
    • accessible, no-args constructor
    • non-final classes
    • accessible, non-final instance methods

    View Slide

  42. Enabling proxying
    @Produces

    @RequestScoped

    public MyService createTransactional(InterceptionFactory ify) {


    ify.ignoreFinalMethods();

    return ify.createInterceptedInstance(new MyService());

    }

    View Slide

  43. Enabling proxying
    @Produces

    @RequestScoped

    public MyService createTransactional(InterceptionFactory ify) {


    ify.ignoreFinalMethods();

    return ify.createInterceptedInstance(new MyService());

    }

    View Slide

  44. Wrap-up
    • Baseline to Java 8, part of Java EE 8
    • Weld 3.0 (May 2017)
    • OpenWebBeans 3.0 (July 2017)
    • Major changes in Java SE, Events, SPI

    View Slide

  45. Get in touch
    Slides – Speakerdeck(mp911.de/cdi-20)
    Code: github.com/mp911de/cdi-2.0
    Web: cdi-spec.org
    Mailing list: [email protected]
    IRC: irc://freenode.net/#cdi-dev
    Twitter: @cdispec // @mp911de
    Github: github.com/cdi-spec
    CDI 2.0 JCP page: jcp.org/en/jsr/summary?id=365

    View Slide