Running your first CDI 2.0 code
Context and Dependency Injection (CDI) is certainly one of the most important APIs for the Java EE platform. In version 2.0, it also works with Java SE.
Nowadays, CDI has an impact on many other APIs in the Java EE platform. As said in an interview for Java EE 8 – The Next Frontier project:
"If there was CDI by the time we created JSF, it would be made completely different." – Ed Burns, JSF Spec Lead
There is a lot of new features in CDI 2.0. This recipe will cover Observer Ordering to give you a quick start.
Getting ready
First, you need to add the right CDI 2.0 dependency to your project. To make things easier at this point, we are going to use CDI SE, the dependency that allows you to use CDI without a Java EE server:
<dependency> <groupId>org.jboss.weld.se</groupId> <artifactId>weld-se-shaded</artifactId> <version>3.0.0.Final</version> </dependency>
How to do it...
This recipe will show you one of the main features introduced by CDI 2.0: Ordered Observers. Now, you can turn the observers job into something predictable:
- First, let's make an event to be observed:
public class MyEvent { private final String value; public MyEvent(String value){ this.value = value; } public String getValue(){ return value; } }
- Now, we build our observers and the server that will fire them:
public class OrderedObserver { public static void main(String[] args){ try(SeContainer container = SeContainerInitializer.newInstance().initialize()){ container .getBeanManager() .fireEvent(new MyEvent("event: " + System.currentTimeMillis())); } } public void thisEventBefore( @Observes @Priority(Interceptor.Priority .APPLICATION - 200) MyEvent event){ System.out.println("thisEventBefore: " + event.getValue()); } public void thisEventAfter( @Observes @Priority(Interceptor.Priority .APPLICATION + 200) MyEvent event){ System.out.println("thisEventAfter: " + event.getValue()); } }
Also, don't forget to add the beans.xml
file into the META-INF
folder:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all"> </beans>
- Once you run it, you should see a result like this:
INFO: WELD-ENV-002003: Weld SE container 353db40d-e670-431d-b7be-4275b1813782 initialized thisEventBefore: event -> 1501818268764 thisEventAfter: event -> 1501818268764
How it works...
First, we are building a server to manage our event and observers:
public static void main(String[] args){ try(SeContainer container = SeContainerInitializer.newInstance().initialize()){ container .getBeanManager() .fireEvent(new ExampleEvent("event: " + System.currentTimeMillis())); } }
This will give us all the resources needed to run the recipe as if it was a Java EE server.
Then we build an observer:
public void thisEventBefore( @Observes @Priority(Interceptor.Priority.APPLICATION - 200) MyEvent event){ System.out.println("thisEventBefore: " + event.getValue()); }
So, we have three important topics:
@Observes
: This annotation is used to tell the server that it needs to watch the events fired withMyEvent
@Priority
: This annotation informs in which priority order this observer needs to run; it receives anint
parameter, and the execution order is ascendantMyEvent event
: The event being observed
On the thisEventBefore
method and thisEventAfter
, we only changed the @Priority
value and the server took care of running it in the right order.
There's more...
The behavior would be exactly the same in a Java EE 8 server. You just wouldn't need SeContainerInitializer
and would need to change the dependencies to the following:
<dependency> <groupId>javax</groupId> <artifactId>javaee-api</artifactId> <version>8.0</version> <scope>provided</scope> </dependency>
See also
- You can stay tuned with everything related to the CDI Specification at http://www.cdi-spec.org/
- The source code of this recipe is at https://github.com/eldermoraes/javaee8-cookbook/tree/master/chapter01/ch01-cdi