What's New in CDI 2.0
JSR 365 Mark Paluch • @mp911de
Slide 2
Slide 2 text
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
Slide 3
Slide 3 text
CanDI
Slide 4
Slide 4 text
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
Slide 5
Slide 5 text
@ApplicationScoped
class UserService {
User createUser() {
return …;
}
}
class UserServlet extends HttpServlet {
@Inject
UserService service;
}
Slide 6
Slide 6 text
@ApplicationScoped
class UserService {
void onUserCreated(@Observes UserEvent event) {
}
}
class UserServlet extends HttpServlet {
@Inject
UserService service;
}
class UserServiceFactory {
@Produces
@ApplicationScoped
UserService createService() {
return new UserService();
}
}
Slide 7
Slide 7 text
Road towards JavaEE 8
• Java 8 baseline
• Spec split: Core/SE/EE
CDI Specification
CDI Core
CDI for
Java SE
CDI for
Java EE
Slide 8
Slide 8 text
Java SE
Slide 9
Slide 9 text
Java SE
• Currently: Implementation-specific in Weld/
OpenWebBean
• Spec Goal: Bootstrap API
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");
}
Slide 19
Slide 19 text
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");
}
Slide 20
Slide 20 text
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");
}
Slide 21
Slide 21 text
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");
}
Slide 22
Slide 22 text
@ObservesAsync
Slide 23
Slide 23 text
Asynchronous Events
• Notify event observers asynchronously
• One or more different threads
• Decoupled from synchronous events
Observing Async Events
public void observer(@ObservesAsync MyEvent payload) {
System.out.println("Yay, I'm called async!");
}
Slide 27
Slide 27 text
How it works
@Observes @ObservesAsync
event.fire(…)
Sync call Not notified
event.fireAsync(…)
Not notified Async call
Slide 28
Slide 28 text
Asynchronous Events
• Exceptions and Synchronization with
CompletionStage
• Active scopes: Request, Application
• Custom scopes depend on the implementation
Slide 29
Slide 29 text
Portable Extensions
Slide 30
Slide 30 text
Meta-Data Builder API
• Standardized API
• CDI 1.0+: Very verbose to create
• AnnotatedTypes, Beans, BeanAttributes, InjectionPoints, and
ObserverMethods
• Builder and Configurator-style
AOP on produced Bean
• CDI 1.0+: Interceptor applied to producer method
• CDI 2.0: InterceptionFactory
@Produces
@Transactional
public MyService produceService() {
...
}
Slide 36
Slide 36 text
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());
}
Slide 37
Slide 37 text
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());
}
Slide 38
Slide 38 text
Proxy matters
Slide 39
Slide 39 text
Proxy injection
@Inject
private MyService myService;
This is a proxy instance
Slide 40
Slide 40 text
Proxy injection
@Inject
@Named("myBean")
private ConcurrentHashMap myService;
/** Implementation for put and putIfAbsent */
final V putVal(K key, V value, boolean onlyIfAbsent)
Slide 41
Slide 41 text
Normal-scoped beans
• Must be proxyable
• accessible, no-args constructor
• non-final classes
• accessible, non-final instance methods