Unleash the power of Context and Dependency Injection (CDI) in a JEE container. The slides go over the 2.0 specification and how each part of the specification can be applied. Code for this can be found on GitHub: https://github.com/bpaskin/JavaExamples/tree/master/CDI2.0Examples/src/com/ibm/example/cdi
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Context and Dependency Injection 2.0
1. Context and Dependency Injection 2.0
Brian S Paskin, Senior Application Architect, R&D Services, IBM Cloud Innovations Lab
Updated 17 January 2019
WebSphere Liberty Lunch and Learn
2. What is Context and Dependency Injection?
2
Context and Dependency Injection (CDI) is part of the Java Enterprise Edition (JEE)
specification (JSR-299 and JSR-330)
– Context: Manage the lifecycle of stateful components using domain specific lifecycle
contexts (Application, Request, Session, et cetera)
– Dependency Injection: Injection of loosely coupled components into client Objects
CDI provides
– Type safety by injecting objects using a String name and is resolved by using Java types
Qualifiers can further distinguish Objects
– Nearly all Objects can be injected (POJOs, EJBs, PersistenceUnit, et cetera)
– Allows for extending the of JEE platform without changing core behavior using the
Service Provider Interface (SPI) that is vendor independent
– Using Interceptors to inject code without having to changing the original code, but cannot
do business logic
– Using Decorators to inject code without having to change the original code, and can do
business logic
– Multiple Events can be triggered synchronously or asynchronous that are loosely coupled
– Integrated support for Expression Language (EL)
3. Configuration file
3
CDI does require a configuration file called beans.xml under certain circumstances
– Belongs under the WEB-INF directory for web applications
– Belongs under META-INF directory for jar or EJB applications
– Needed for Interceptors, Decorators and Alternatives
– Needed for changing default discovery mode, which is annotated.
Bean discover modes
– None – CDI is disabled
– Annotated (default) – only class level annotations are processed
– All – All components are processed
5. Simple Injection
5
@Inject is used to specify that an Object is to be injected into the current client Object
An Object that implements an Interface can be injected
– An interface can be injected in cases where there is only one Object implementing it
@Inject private City city;
6. Retrieving Beans By Name
6
When more than one Object implements an Interface @Named should be used
– Class should be annotated with @Named
– If no @Named is found, then the class name is used by default
– @Inject must include @Named
@Named("Rome")
public class Rome implements City {
@Named("Cologne")
public class Cologne implements City {
@Inject @Named("Rome") private City city;
7. Lazy Injection
7
When the Interface is known, but not Objects that implement the interface are not known
– Dynamically obtain instances of Beans using Instance<T>
– Each instance can be acted upon
@Inject private Instance<City> instance;
8. Context Scopes
8
Tells the container when a Bean is created and destroyed
Objects are annotated with a context scope
– Objects not annotated are given the default annotation @Dependent
@Dependent – serves exactly one client Bean and has the same lifecycle of the client Bean
@RequestScoped – lasts through a single HTTP request
@SessionScoped – lasts through multiple HTTP requests
@ApplicationScoped – lasts through the entire life of the application for all users
@ConversationScope – exists in developer controlled boundaries across multiple
requests and long running conversations.
– Session boundaries cannot be crossed
Developers can create their own scopes @RequestScoped
public class ScopeBean1 {
@ApplicationScoped
public class ScopeBean2 {
9. Qualifiers
9
Provides various implementations of a particular type of bean
– Uses @Qualifer with the @Retention policy and @Target elements
@Retention is how long annotations with the annotated type are to be retained
– Usually Runtime, the default, since CDI works with injection at runtime
@Target specifies the program elements that the Qualifier can apply
The name of the Qualifier is the annotation that is applied to a bean
@Qualifier
@Target({ TYPE, FIELD, METHOD, PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface Favorite {
@Favorite
public class NewFavoriteDoctor extends FavoriteDoctor {
@Inject @Favorite private FavoriteDoctor doctor2;
10. Producers
10
Provides a way to inject Objects that are not Beans
Executes the @Produces annotated method when the Object is injected
– Can include a scope
Requires a Qualifier to specify that the injection will run the annotated method on the Bean
Disposers are optional and are called at end of life and take the parameter of the Object that
is produced and is annotated with @Disposes
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER })
public @interface Favorite {
public @Produces @Favorite String getDoctor() {
@Inject @Favorite String name;
public void regenerate(@Disposes String instance) {
11. Events
11
CDI Events are based on the Observer/Observable pattern
– Does not require compile time dependencies
– Events can be synchronous or asynchronous
– Can trigger multiple events with priority
A Qualifier is required
An Object is created that represents the Event type
– The methods would define if the events are intercepted synchronously or asynchronously
and their priority
The Event<T> is injected with the Qualifier in an Object that needs to fire events
There are built in events
– beginRequest, endRequest, beginSession, endSession
12. Events
12
@Qualifier
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER })
public @interface Doctor {
public void firstObserver(@Observes
@Priority(Interceptor.Priority.APPLICATION) @Doctor Regenerate doctor)
public void secondObserver(@Observes
@Priority(Interceptor.Priority.APPLICATION+1) @Doctor Regenerate doctor)
@Inject @Doctor private Event<Regenerate> doctor;
doctor.fire(new Regenerate());
13. Interceptors and Decorators
13
Both are part of aspect oriented mechanism
Interceptors are technically oriented and used mainly for transactions, security, and logging
– Can be bound to any bean or bean method
Decorators are business oriented and are used to chain the behavior of a bean
– Bound to a bean class
Both require entries in the beans.xml to active or @Priority to specify globally
<interceptors>
<class>com.ibm.example.cdi.interceptor.LoggingInterceptor</class>
</interceptors>
<decorators>
<class>com.ibm.example.cdi.decorator.LoggingDecorator</class>
</decorators>
14. Interceptors
14
Interceptors usually contain the annotation @AroundInvoke which specifies the method to
be run when the interceptor is invoked
The methods @PostConstruct, @PreDestroy, @PrePassivate, and @PostActivate
to specify lifecycle callback interceptors
The method @AroundTimeout can be used to specify an EJB timeout interceptor
Interceptor classes can contain more than one Interceptor methods but only one of each type
One or more Interceptor Binding Types must be defined
– Associate annotation with target bean or method
– Similar to Qualifiers but annotated with @InterceptorBinding
– Can include the annotation @Inherited to specify it can be inherited by the superclass
– May declare other Interceptor Bindings
Interceptor classes are annotated with @Interceptor and the Interceptor Binding
@AroundInvoke takes an InovationContext parameter and can throw an Exception
17. Decorators
17
Decorators implement an interface and are annotated with the annotation @Decorator
More than Decorator can be called with the annotation @Priority and providing the order
A Delegate injection entry point is required using @Delegate
– Can be field, constructor parameter, or initializer method
– Allows to get handle of called Object
– Only one Delegate is allowed per Decorator
The code in Decorator overrides the code in the actual class using the Delegate
18. Decorators
18
public interface Logging {
public class LoggingEntry implements Logging {
@Decorator
public class LoggingDecorator implements Logging {
@Inject @Delegate @Any
private Logging logging;
@Inject private LoggingEntry entry;
19. Alternatives
19
Used when there is more than one version of a Bean and is determined at deployment time
The class that is a different version is annotated with @Alternative
The Alternative class must be placed in the beans.xml to activate
Multiple Alternative classes can be invoked using @Priority and providing the order
20. Alternatives
20
public interface Doctor {
public class FavoriteDoctor implements Doctor {
@Alternative
public class FavoriteDoctorAlternative implements Doctor {
@Inject private Doctor doctor;
<alternatives>
<class>com.ibm.example.cdi.alternative.FavoriteDoctorAlternative</class>
</alternatives>
21. Utilizing the BeanManager
21
The BeanManager allows for extensions to interact with the container
Any Bean can injected the BeanManager
An instance of the BeanManager can be obtained using JNDI looking up
java:comp/BeanManager
Once obtained can use introspection on Beans or change certain behaviors of CDI
@Inject private BeanManager bm;
22. More information
22
Context and Dependency Injection for Java EE (JEE 8)
Examples used for this presentations from GitHub
Learning CDI