28 August 2015
Introduction to CDI
1
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
Agenda
2
Introduction to CDI
• Java EE dependency injection standard
• Can also be used in Java SE environments with
some help
• Strongly typed and type safe
• Provides context management
• Activated by default since CDI 1.1
• Use beans.xml to activate alternative beans, etc.
• Highly Extensible via CDI SPI (not covered here)
What is CDI?
3
Introduction to CDI
• Managed Beans are basic components
• Managed by the container
• Have a lifecycle
• Can be intercepted (technical concerns)
and decorated (business concerns)
• Can be injected
• Are accessible outside CDI code
CDI Beans
4
Agenda
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
5
Basic Dependency Injection
public class HowdyService {
public String howdy() {
return "Howdy!";
}
}
This is a bean
6
Basic Dependency Injection
public class MyBean {
private HowdyService service;
@Inject
public MyBean(HowdyService service) {
this.service = service;
}
}
Dependency Injection in Constructors
7
Basic Dependency Injection
public class MyBean {
private HowdyService service;
@Inject
public void setService(HowdyService service) {
this.service = service;
}
}
Dependency Injection in Setter
8
Basic Dependency Injection
public class MyBean {
@Inject
private HowdyService service;
public void sayHowdy() {
display(service.howdy());
}
}
Dependency Injection in Fields
9
Basic Dependency Injection
This Works!
public class MyBean {
@Inject Service<User> userService;
@Inject Service<Staff> staffService;
}
No Type Erasure in CDI
10
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
11
Using Qualifiers to Distinguish Beans of the Same Type
public interface HelloService {
public String hello();
}
public class TexanHelloService implements HelloService {
public String hello() {
return "Howdy!";
}
}
public class AustralianHelloService implements HelloService {
public String hello() {
return "G’day!";
}
}
Multiple Service Implementations
12
Using Qualifiers to Distinguish Beans of the Same Type
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD, PARAMETER})
public @interface Texan {}
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD, PARAMETER})
public @interface Australian {}
We Create Qualifiers
13
Using Qualifiers to Distinguish Beans of the Same Type
@Texan
public class TexanHelloService implements HelloService {
public String hello() {
return "Howdy!";
}
}
@Australian
public class AussieHelloService implements HelloService {
public String hello() {
return "G’day!";
}
}
And Add Them to Our Implementations
14
Using Qualifiers to Distinguish Beans of the Same Type
public class MyTexanBean {
@Inject @Texan HelloService service;
public void displayHello() {
display(service.hello());
}
}
public class MyAussieBean {
@Inject @Australian HelloService service;
public void displayHello() {
display(service.hello());
}
}
And Specify at our Injection Site
15
Using Qualifiers to Distinguish Beans of the Same Type
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE, METHOD, PARAMETER})
public @interface Language {
public enum Languages {
TEXAN, AUSTRALIAN
}
Languages value();
@Nonbinding String description() default "";
}
Qualifiers can have Members
16
Using Qualifiers to Distinguish Beans of the Same Type
@Language(TEXAN)
public class TexanHelloService implements HelloService {
public String hello() {
return "Howdy!";
}
}
@Language(AUSTRALIAN)
public class AussieHelloService implements HelloService {
public String hello() {
return "G’day!";
}
}
Class definition for Qualifiers with Members
17
Using Qualifiers to Distinguish Beans of the Same Type
public class MyTexanBean {
@Inject @Language(TEXAN) HelloService service;
public void displayHello() {
display(service.hello());
}
}
public class MyAussieBean {
@Inject @Language(AUSTRALIAN) HelloService service;
public void displayHello() {
display(service.hello());
}
}
Injection using Qualifiers with Members
18
Using Qualifiers to Distinguish Beans of the Same Type
public class MyTexanBean {
@Inject @Texan HelloService service;
public void displayHello() {
display(service.hello());
}
}
@Texan @Console @Secured
public class TexanHelloService implements HelloService {
public String hello() {
return "Howdy!";
}
}
Multiple Qualifiers
19
Using Qualifiers to Distinguish Beans of the Same Type
public class MyTexanBean {
@Inject @Texan @Console HelloService service;
public void displayHello() {
display(service.hello());
}
}
@Texan @Console @Secured
public class TexanHelloService implements HelloService {
public String hello() {
return "Howdy!";
}
}
Multiple Qualifiers
20
Using Qualifiers to Distinguish Beans of the Same Type
public class MyTexanBean {
@Inject @Texan @Console @Secured HelloService service;
public void displayHello() {
display(service.hello());
}
}
@Texan @Console @Secured
public class TexanHelloService implements HelloService {
public String hello() {
return "Howdy!";
}
}
Multiple Qualifiers
21
Using Qualifiers to Distinguish Beans of the Same Type
public class MyTexanBean {
@Inject @Texan @Console @Secured HelloService service;
public void displayHello() {
display(service.hello());
}
}
@Texan @Console
public class TexanHelloService implements HelloService {
public String hello() {
return "Howdy!";
}
}
Multiple Qualifiers – Won’t work
22
Using Qualifiers to Distinguish Beans of the Same Type
@Default
@Any
@Named
Reserved Qualifiers
23
Using Qualifiers to Distinguish Beans of the Same Type
public class MyBean {
@Inject @Any
Instance<HelloService> service;
public void displayHello() {
HelloService helloService =
service.select(new AnnotationLiteral<Texan>(){}).get();
display(helloService.hello());
}
}
Programmatic Bean Lookup (a.k.a. Lazy Injection)
24
Using Qualifiers to Distinguish Beans of the Same Type
@Texan @Vetoed
public class TexanHelloService implements HelloService {
public String hello() {
return "Howdy!";
}
}
package-info.java class:
@Vetoed
package cdi_experiments;
import javax.enterprise.inject.Vetoed;
Ignoring Beans and Packages with @Vetoed
25
Using Qualifiers to Distinguish Beans of the Same Type
@Texan @Alternative
public class MyHowdyYallService implements HelloService {
public String hello() {
return "Howdy y'all!";
}
}
<beans …>
<alternatives>
<class>cdi_experiments.MyHowdyYallService</class>
</alternatives>
</beans>
Specifying and using Alternative Beans
26
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
27
Contexts
Help the container to choose when a bean should be intstantiated and destroyed
Enforce singleton pattern for a given context
Built-in CDI contexts:
• @Dependent (default)
• @ApplicationScoped, @SessionScoped, @RequestSCoped
• @ConversationScoped
• @Singleton
You can create your own scope
Contexts Manage Bean Lifecycle
28
Contexts
@SessionScoped
public class CartBean {
public void addItem(Item item) {
...
}
}
A shopping cart is almost always tied to a user’s session,
so using the @SessionScoped context makes the most
sense.
Choosing the Right Context
29
Contexts
@ApplicationScoped
public class CartBean {
public void addItem(Item item) {
...
}
}
BAD IDEA! Having a single cart used across all users
doesn’t make any sense.
30
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
31
Producers and Disposers
@Produces
public OldRanchHand oldRanchHandProducer() {
return new OldRanchHand();
}
…
@Inject OldRanchHand ranchHand;
The return type and the injection type are identical. CDI uses this type information to inject produced
values.
To inject different values into different injection points of the same type, use qualifiers
Method producers can be used to generate complex objects
Create a Bean from any Class
32
Producers and Disposers
@Produces
public Logger produceLog(InjectionPoint injectionPoint) {
return Logger.getLogger(injectionPoint.getMember()
.getDeclaringClass().getName());
}
Getting Injection Point Information
33
Producers and Disposers
@Produces
public <K, V> Map<K, V> produceMap(InjectionPoint ip) {
if (valueIsNumber(ip.getType())) {
return new TreeMap<K, V>();
}
return new HashMap<K, V>();
}
No Type Erasure Enables Fancy Stuff
34
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
35
Events
public class MyTexanBean {
@Inject Event<HelloService> helloEvent;
@Inject @Texan HelloService service;
public void displayHello() {
display(service.hello());
}
public void iSaidHowdy(HelloService helloService) {
helloEvent.fire(helloService);
}
}
public class HelloListenerBean {
public void listenForHello(@Observes HelloService hello) {
System.out.println(hello.hello() + " to you too!");
}
}
36
Events
public class HelloListenerBean {
public void listenForHello(@Observes @Texan HelloService hello) {
System.out.println(hello.hello() + " to you too!");
}
}
Qualifiers on Observers
37
Events
The producer must wait for all observers to execute before
continuing
If any observer throws an exception, all remaining observer
methods are not called and the exception is thrown by the
firing observing method
Observers have no priority in CDI 1.1, but is on the
roadmap for 2.0
Some Caveats
38
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
39
Interceptors
Classes that provide technical cross-cutting functionality
are interceptors
Technical cross-cutting concerns include:
• Transactions
• Security
• Logging
Interceptors are not enabled by default, but can be enabled
and ordered in beans.xml
Interceptors can have multiple qualifiers
Interceptors
40
Interceptors
Interceptor bindings are qualifiers that instruct the CDI
container to intercept a method or all methods on a class
@InterceptorBinding
@Target({METHOD, TYPE})
@Retention(RUNTIME)
public @interface Loggable {}
Qualified Interceptor Binding
41
Interceptors
@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());
}
}
}
Interceptor Class
42
Interceptors
@Loggable
public class MyTexanBean {
@Inject @Texan HelloService service;
public void displayHello() {
display(service.hello());
}
}
Intercepting a Class or Method
43
Interceptors
@Interceptor @Loggable
public class FriendlyCowboy {
@PostConstruct
public void smile(InvocationContext invocationContext) {
//smile
}
@PreDestroy
public void tipHat(InvocationContext invocationContext) {
//tip hat
}
}
Lifecycle Interceptors
44
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
45
Decorators
Classes that provide additional business functionality are decorators
Interceptors are called before decorators
Decorator classes must implement the same interface(s) as the
classes that they are decorating
Can be abstract if it only decorates some of the methods in the
interface
Enabled in the <decorators> section in the beans.xml file and can be
enabled and ordered in the beans.xml and via the @Priority
annotation
Decorators
46
Decorators
@Decorator
public abstract class HelloDec implements HelloService {
// The decorated service may be restricted with qualifiers
@Inject
@Delegate
HelloService service;
public String hello() {
return service.hello() + "-decorated";
}
}
Short Example
47
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
48
CDI in Java SE
Currently possible through the DeltaSpike library
Slated for standardization in CDI 2.0
public class MainApp {
public static void main(String[] args) {
CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer();
cdiContainer.boot();
// Starting the application-context enables use of @ApplicationScoped beans
ContextControl contextControl = cdiContainer.getContextControl();
contextControl.startContext(ApplicationScoped.class);
// You can use CDI here
//...
cdiContainer.shutdown();
}
}
CDI – Not Just for JEE!
49
1 Introduction to CDI
2 Basic Dependency Injection
3 Using Qualifiers to Distinguish Beans of the Same Type
4 Contexts
5 Producers and Disposers
6 Events
7 Interceptors
8 Decorators
9 CDI in Java SE
10 Using CDI and JPA Together
50
Using CDI and JPA Together
CDI Beans and JPA Beans have different lifecycles
As a result, CDI Beans can’t be injected directly into JPA Beans
EntityListeners can be used to bridge CDI and JPA when needed
CDI and JPA – Friends at Last
51
Using CDI and JPA Together
@Entity
@EntityListeners(PostListener.class)
public class Post implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "CREATED_DATE")
private Date created;
@Column(name = "LAST_MODIFIED_DATE")
private Date lastModified;
public Date getCreated() { return created; }
public void setCreated(Date created) { this.created = created; }
public Date getLastModified() { return lastModified; }
public void setLastModified(Date lastModified) { this.lastModified = lastModified;}
}
The JPA Class
52
Using CDI and JPA Together
public class PostListener {
@Inject Logger log;
@PrePersist
public void prePresist(Object o) {
log.info("call prePresist");
if (o instanceof Post) {
Post post = (Post) o;
final Date created = new Date();
post.setCreated(created);
post.setLastModified(created);
}
}
@PreUpdate
public void preUpdate(Object o) {
log.info("call preUpdate");
if (o instanceof Post) {
Post post = (Post) o;
post.setLastModified(new Date());
}
}
}

Introduction to CDI

  • 1.
  • 2.
    1 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together Agenda
  • 3.
    2 Introduction to CDI •Java EE dependency injection standard • Can also be used in Java SE environments with some help • Strongly typed and type safe • Provides context management • Activated by default since CDI 1.1 • Use beans.xml to activate alternative beans, etc. • Highly Extensible via CDI SPI (not covered here) What is CDI?
  • 4.
    3 Introduction to CDI •Managed Beans are basic components • Managed by the container • Have a lifecycle • Can be intercepted (technical concerns) and decorated (business concerns) • Can be injected • Are accessible outside CDI code CDI Beans
  • 5.
    4 Agenda 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together
  • 6.
    5 Basic Dependency Injection publicclass HowdyService { public String howdy() { return "Howdy!"; } } This is a bean
  • 7.
    6 Basic Dependency Injection publicclass MyBean { private HowdyService service; @Inject public MyBean(HowdyService service) { this.service = service; } } Dependency Injection in Constructors
  • 8.
    7 Basic Dependency Injection publicclass MyBean { private HowdyService service; @Inject public void setService(HowdyService service) { this.service = service; } } Dependency Injection in Setter
  • 9.
    8 Basic Dependency Injection publicclass MyBean { @Inject private HowdyService service; public void sayHowdy() { display(service.howdy()); } } Dependency Injection in Fields
  • 10.
    9 Basic Dependency Injection ThisWorks! public class MyBean { @Inject Service<User> userService; @Inject Service<Staff> staffService; } No Type Erasure in CDI
  • 11.
    10 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together
  • 12.
    11 Using Qualifiers toDistinguish Beans of the Same Type public interface HelloService { public String hello(); } public class TexanHelloService implements HelloService { public String hello() { return "Howdy!"; } } public class AustralianHelloService implements HelloService { public String hello() { return "G’day!"; } } Multiple Service Implementations
  • 13.
    12 Using Qualifiers toDistinguish Beans of the Same Type @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface Texan {} @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface Australian {} We Create Qualifiers
  • 14.
    13 Using Qualifiers toDistinguish Beans of the Same Type @Texan public class TexanHelloService implements HelloService { public String hello() { return "Howdy!"; } } @Australian public class AussieHelloService implements HelloService { public String hello() { return "G’day!"; } } And Add Them to Our Implementations
  • 15.
    14 Using Qualifiers toDistinguish Beans of the Same Type public class MyTexanBean { @Inject @Texan HelloService service; public void displayHello() { display(service.hello()); } } public class MyAussieBean { @Inject @Australian HelloService service; public void displayHello() { display(service.hello()); } } And Specify at our Injection Site
  • 16.
    15 Using Qualifiers toDistinguish Beans of the Same Type @Qualifier @Retention(RUNTIME) @Target({FIELD, TYPE, METHOD, PARAMETER}) public @interface Language { public enum Languages { TEXAN, AUSTRALIAN } Languages value(); @Nonbinding String description() default ""; } Qualifiers can have Members
  • 17.
    16 Using Qualifiers toDistinguish Beans of the Same Type @Language(TEXAN) public class TexanHelloService implements HelloService { public String hello() { return "Howdy!"; } } @Language(AUSTRALIAN) public class AussieHelloService implements HelloService { public String hello() { return "G’day!"; } } Class definition for Qualifiers with Members
  • 18.
    17 Using Qualifiers toDistinguish Beans of the Same Type public class MyTexanBean { @Inject @Language(TEXAN) HelloService service; public void displayHello() { display(service.hello()); } } public class MyAussieBean { @Inject @Language(AUSTRALIAN) HelloService service; public void displayHello() { display(service.hello()); } } Injection using Qualifiers with Members
  • 19.
    18 Using Qualifiers toDistinguish Beans of the Same Type public class MyTexanBean { @Inject @Texan HelloService service; public void displayHello() { display(service.hello()); } } @Texan @Console @Secured public class TexanHelloService implements HelloService { public String hello() { return "Howdy!"; } } Multiple Qualifiers
  • 20.
    19 Using Qualifiers toDistinguish Beans of the Same Type public class MyTexanBean { @Inject @Texan @Console HelloService service; public void displayHello() { display(service.hello()); } } @Texan @Console @Secured public class TexanHelloService implements HelloService { public String hello() { return "Howdy!"; } } Multiple Qualifiers
  • 21.
    20 Using Qualifiers toDistinguish Beans of the Same Type public class MyTexanBean { @Inject @Texan @Console @Secured HelloService service; public void displayHello() { display(service.hello()); } } @Texan @Console @Secured public class TexanHelloService implements HelloService { public String hello() { return "Howdy!"; } } Multiple Qualifiers
  • 22.
    21 Using Qualifiers toDistinguish Beans of the Same Type public class MyTexanBean { @Inject @Texan @Console @Secured HelloService service; public void displayHello() { display(service.hello()); } } @Texan @Console public class TexanHelloService implements HelloService { public String hello() { return "Howdy!"; } } Multiple Qualifiers – Won’t work
  • 23.
    22 Using Qualifiers toDistinguish Beans of the Same Type @Default @Any @Named Reserved Qualifiers
  • 24.
    23 Using Qualifiers toDistinguish Beans of the Same Type public class MyBean { @Inject @Any Instance<HelloService> service; public void displayHello() { HelloService helloService = service.select(new AnnotationLiteral<Texan>(){}).get(); display(helloService.hello()); } } Programmatic Bean Lookup (a.k.a. Lazy Injection)
  • 25.
    24 Using Qualifiers toDistinguish Beans of the Same Type @Texan @Vetoed public class TexanHelloService implements HelloService { public String hello() { return "Howdy!"; } } package-info.java class: @Vetoed package cdi_experiments; import javax.enterprise.inject.Vetoed; Ignoring Beans and Packages with @Vetoed
  • 26.
    25 Using Qualifiers toDistinguish Beans of the Same Type @Texan @Alternative public class MyHowdyYallService implements HelloService { public String hello() { return "Howdy y'all!"; } } <beans …> <alternatives> <class>cdi_experiments.MyHowdyYallService</class> </alternatives> </beans> Specifying and using Alternative Beans
  • 27.
    26 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together
  • 28.
    27 Contexts Help the containerto choose when a bean should be intstantiated and destroyed Enforce singleton pattern for a given context Built-in CDI contexts: • @Dependent (default) • @ApplicationScoped, @SessionScoped, @RequestSCoped • @ConversationScoped • @Singleton You can create your own scope Contexts Manage Bean Lifecycle
  • 29.
    28 Contexts @SessionScoped public class CartBean{ public void addItem(Item item) { ... } } A shopping cart is almost always tied to a user’s session, so using the @SessionScoped context makes the most sense. Choosing the Right Context
  • 30.
    29 Contexts @ApplicationScoped public class CartBean{ public void addItem(Item item) { ... } } BAD IDEA! Having a single cart used across all users doesn’t make any sense.
  • 31.
    30 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together
  • 32.
    31 Producers and Disposers @Produces publicOldRanchHand oldRanchHandProducer() { return new OldRanchHand(); } … @Inject OldRanchHand ranchHand; The return type and the injection type are identical. CDI uses this type information to inject produced values. To inject different values into different injection points of the same type, use qualifiers Method producers can be used to generate complex objects Create a Bean from any Class
  • 33.
    32 Producers and Disposers @Produces publicLogger produceLog(InjectionPoint injectionPoint) { return Logger.getLogger(injectionPoint.getMember() .getDeclaringClass().getName()); } Getting Injection Point Information
  • 34.
    33 Producers and Disposers @Produces public<K, V> Map<K, V> produceMap(InjectionPoint ip) { if (valueIsNumber(ip.getType())) { return new TreeMap<K, V>(); } return new HashMap<K, V>(); } No Type Erasure Enables Fancy Stuff
  • 35.
    34 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together
  • 36.
    35 Events public class MyTexanBean{ @Inject Event<HelloService> helloEvent; @Inject @Texan HelloService service; public void displayHello() { display(service.hello()); } public void iSaidHowdy(HelloService helloService) { helloEvent.fire(helloService); } } public class HelloListenerBean { public void listenForHello(@Observes HelloService hello) { System.out.println(hello.hello() + " to you too!"); } }
  • 37.
    36 Events public class HelloListenerBean{ public void listenForHello(@Observes @Texan HelloService hello) { System.out.println(hello.hello() + " to you too!"); } } Qualifiers on Observers
  • 38.
    37 Events The producer mustwait for all observers to execute before continuing If any observer throws an exception, all remaining observer methods are not called and the exception is thrown by the firing observing method Observers have no priority in CDI 1.1, but is on the roadmap for 2.0 Some Caveats
  • 39.
    38 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together
  • 40.
    39 Interceptors Classes that providetechnical cross-cutting functionality are interceptors Technical cross-cutting concerns include: • Transactions • Security • Logging Interceptors are not enabled by default, but can be enabled and ordered in beans.xml Interceptors can have multiple qualifiers Interceptors
  • 41.
    40 Interceptors Interceptor bindings arequalifiers that instruct the CDI container to intercept a method or all methods on a class @InterceptorBinding @Target({METHOD, TYPE}) @Retention(RUNTIME) public @interface Loggable {} Qualified Interceptor Binding
  • 42.
    41 Interceptors @Interceptor @Loggable @Priority(Interceptor.Priority.APPLICATION) public classLogInterceptor { @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()); } } } Interceptor Class
  • 43.
    42 Interceptors @Loggable public class MyTexanBean{ @Inject @Texan HelloService service; public void displayHello() { display(service.hello()); } } Intercepting a Class or Method
  • 44.
    43 Interceptors @Interceptor @Loggable public classFriendlyCowboy { @PostConstruct public void smile(InvocationContext invocationContext) { //smile } @PreDestroy public void tipHat(InvocationContext invocationContext) { //tip hat } } Lifecycle Interceptors
  • 45.
    44 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together
  • 46.
    45 Decorators Classes that provideadditional business functionality are decorators Interceptors are called before decorators Decorator classes must implement the same interface(s) as the classes that they are decorating Can be abstract if it only decorates some of the methods in the interface Enabled in the <decorators> section in the beans.xml file and can be enabled and ordered in the beans.xml and via the @Priority annotation Decorators
  • 47.
    46 Decorators @Decorator public abstract classHelloDec implements HelloService { // The decorated service may be restricted with qualifiers @Inject @Delegate HelloService service; public String hello() { return service.hello() + "-decorated"; } } Short Example
  • 48.
    47 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together
  • 49.
    48 CDI in JavaSE Currently possible through the DeltaSpike library Slated for standardization in CDI 2.0 public class MainApp { public static void main(String[] args) { CdiContainer cdiContainer = CdiContainerLoader.getCdiContainer(); cdiContainer.boot(); // Starting the application-context enables use of @ApplicationScoped beans ContextControl contextControl = cdiContainer.getContextControl(); contextControl.startContext(ApplicationScoped.class); // You can use CDI here //... cdiContainer.shutdown(); } } CDI – Not Just for JEE!
  • 50.
    49 1 Introduction toCDI 2 Basic Dependency Injection 3 Using Qualifiers to Distinguish Beans of the Same Type 4 Contexts 5 Producers and Disposers 6 Events 7 Interceptors 8 Decorators 9 CDI in Java SE 10 Using CDI and JPA Together
  • 51.
    50 Using CDI andJPA Together CDI Beans and JPA Beans have different lifecycles As a result, CDI Beans can’t be injected directly into JPA Beans EntityListeners can be used to bridge CDI and JPA when needed CDI and JPA – Friends at Last
  • 52.
    51 Using CDI andJPA Together @Entity @EntityListeners(PostListener.class) public class Post implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long id; @Column(name = "CREATED_DATE") private Date created; @Column(name = "LAST_MODIFIED_DATE") private Date lastModified; public Date getCreated() { return created; } public void setCreated(Date created) { this.created = created; } public Date getLastModified() { return lastModified; } public void setLastModified(Date lastModified) { this.lastModified = lastModified;} } The JPA Class
  • 53.
    52 Using CDI andJPA Together public class PostListener { @Inject Logger log; @PrePersist public void prePresist(Object o) { log.info("call prePresist"); if (o instanceof Post) { Post post = (Post) o; final Date created = new Date(); post.setCreated(created); post.setLastModified(created); } } @PreUpdate public void preUpdate(Object o) { log.info("call preUpdate"); if (o instanceof Post) { Post post = (Post) o; post.setLastModified(new Date()); } } }

Editor's Notes

  • #11 Two injection points with different parameterized types. CDI can differentiate between these two types, without the need to introduce extra code. But what if we have two implementations of the same interface?
  • #13 Here we have two implementations of the HelloService
  • #16 CDI can now determine which implementation you want to use
  • #17 Ideally, you’ll want to have Boolean and Enum members to keep things as type-safe and controlled as possible. The @Nonbinding annotation indicates that the description value will not be considered for injection target matching
  • #20 The container will find the HelloService qualified with the Texan qualifier
  • #21 The container will find the HelloService qualified with both with the Texan and Console qualifiers
  • #22 The container will find the HelloService qualified with both with the Texan, Console, and Secured qualifiers
  • #23 However, the container will not find the HelloService qualified with the Texan, Console, and Secured qualifiers since there is no bean with all qualifier types – we only have Texan and Console qualifiers on the TexanHelloService
  • #24 @Default is the qualifier that is applied to all beans that don’t have qualifiers @Any – used in programmatic lookup @Named – exception in strong typing – used to give a name to a bean to access bean via JSF view or JSP page
  • #25 The Any qualifer says to inject an instance of HelloService regardless of their qualifier. Here we’re selecting the Texan service through the use of the AnnotationLiteral abstract class, which supports inline instantiation of annotation type instances.
  • #26 In this case, the TexanHelloService class will be ignored by the CDI container since it is marked as @Vetoed To veto an entire package, mark the package as @Vetoed in the package-info.java class
  • #27 Instead of saying Howdy! all injected Texan beans will say Howdy y’all since it is activated in the alternatives section of the beans.xml Useful both in testing to inject test beans to isolate behavior Useful in production environments to enable different behavior depending on requirements
  • #33 Turns a POJO into a CDI bean and alllows 3rd party frameworks to be used by CDI by exposing their objects as CDI beans Producers allow additional control over object creation You can also have @Alternative producers
  • #34 The InjectionPoint class allows for programmatic retrieval of some information about the injection site class.
  • #35 Since CDI doesn’t erase type information, we can use generic type information in our code
  • #37 Events allow for the decoupling of producers and consumers Require no compile-time dependencies
  • #38 Events can be qualified to only listen for events from specific beans
  • #41 Interceptors can have multiple qualifiers or can use qualifiers with members to allow the CDI container to differentiate interceptors Interceptors can be @Vetoed
  • #43 Interceptor classes must be annotated / qualified with the @Interceptor annotation and at least one other qualifier The intercepting method must be annotated with @AroundInvoke Interceptor methods must take an InvocationContext type as a parameter and return Object and call the proceed method once it’s done. Wrap the proceed() method call in a try/finally block to execute code if the intercepted method needs to have additional code executed after it completes / exits Interceptors are executed in the order they are defined in beans.xml, but only in that archive Interceptors can be ordered for an entire application using the @Priority annotation -- smaller priority called first.  Defined in the qualifier / annotation class
  • #44 Interceptor annotations can be declared on individual methods, or they can be placed on all public methods by annotating the class with the interceptor
  • #45 Annotate the method on the CDI bean you want executed at the appropriate point in the life cycle Lifecycle @Interceptor beans can be defined and can be applied to multiple CDI managed beans.   The methods annotated with @PostConstruct and @PreDestroy must take an InvocationContext as a parameter and return void
  • #50 Starting the container does not automatically start all CDI Contexts. Contexts must be started independently using DeltaSpike’s provided ContextControl class.
  • #53 Bare bones blog post JPA example From http://hantsy.blogspot.com/2013/12/jpa-21-cdi-support.html
  • #54 Logger is injected and invoked on JPA lifecycle event occurrences