In one of my older blog posts, I had written about what does not work as far as WebSocket and CDI integration within the Java EE Platform 😉 This one talks about what’s possible with CDI in terms of
- Dependency Injection
- Interceptors
Before you dig in, here is a summary
Feature | Supported in EJB Annotated WebSocket endpoint ? | Supported in Plain WebSocket endpoint ? |
---|---|---|
Inject CDI managed beans | yes | yes |
Use CDI interceptors | yes | yes |
DI support
It is possible to inject CDI managed beans in WebSocket endpoints. All injection targets are supported i.e. field, constructor, method
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@RequestScoped //CDI annotation | |
public class CDIManagedBean { | |
…. | |
} | |
@ServerEndpoint("/stocks/") | |
public class StockTracker { | |
@Inject | |
private CDIManagedBean cdiBean; | |
@OnOpen | |
public void onOpenCallback(Session s){ | |
cdiBean.doSomething(); //use injected instance | |
} | |
} | |
// works with an EJB as well | |
@ServerEndpoint("/weather/") | |
@Stateless | |
public class WeatherTracker { | |
@Inject | |
private CDIManagedBean cdiBean; | |
@OnOpen | |
public void onOpenCallback(Session s){ | |
cdiBean.doSomething(); //use injected instance | |
} | |
} |
Interceptor support
You can use interceptors to implement cross-cutting concerns in for the business methods in your WebSocket endpoints
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//the interceptor binding | |
@Inherited | |
@InterceptorBinding | |
@Retention(RUNTIME) | |
@Target({METHOD, TYPE}) | |
public @interface LoggerInterceptorBinding {} | |
//Implement our interceptor and bind it | |
@Interceptor | |
@LoggerInterceptorBinding | |
public class CDIBasedLoggingInterceptor { | |
@AroundInvoke | |
public Object log(InvocationContext ic) throws Exception { | |
Object retVal = null; | |
String clazz = ic.getTarget().getClass().getName(); | |
try { | |
Logger.enter(clazz); | |
retVal = ic.proceed(); | |
} catch (Exception e) { | |
throw e; | |
} finally { | |
Logger.exit(clazz); | |
} | |
return retVal; | |
} | |
} | |
//Apply the interceptor where needed (via the binding) | |
@ServerEndpoint("/chat/") | |
public class ChatEndpoint { | |
@LoggerInterceptorBinding //binding the CDIBasedLoggingInterceptor | |
@OnOpen | |
public void onChatMsgRecieved { | |
//…. | |
} | |
} | |
//don't forget to specify the interceptor in beans.xml (compulsory)\ | |
<?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"> | |
<interceptors> | |
<class>com.wordpress.abhirockzz.test.CDIBasedInerceptor</class> | |
</interceptors> | |
</beans> |
Good to know
Now that you have an idea about how WebSockets work with CDI in terms of Dependency injection and Interceptors, here are some other points
- DI and interceptors are supported for both server and client endpoints running within a JavaEE container
- DI and interceptors are supported for both annotated and programatic endpoints running within a JavaEE container
- container managed injection features are not available to WebSocket endpoints which override the container implemented initialization (using the
ServerEndpointConfig.Configurator
)
Additional reading
- eBook – Java WebSocket API Handbook
- WebSocket specification
- Previous blogs related to WebSocket
- CDI specification
Cheers!
Pingback: Java Weekly 103: Garbage collection, CDI 2.0 and productivity
Thanks, nice post.
LikeLike
Thanks! Glad you liked it
LikeLike