I am developing a Java EE application with no http interface: it uses only MQTT for sending/receiveing data.
I am wondering whether CDI @SessionScoped
and @RequestScoped
apply to this scenario or I have to define custom scopes to handle client's requests.
I tried a simple application that injects a @SessionScoped
or @RequestScoped
bean in mqtt receive callback and I got an exception saying that I have no active context.
Is it possible to activate a context programmatically so that beans' lifecycle follow the chosen scope?
PS: when I post the question I was not too lazy to make that simple test but I was courious to go deeper in CDI scope theory...and still I am..
CDI places beans of contextual scope in the context whose lifecycle is defined by the Java EE specifications. For example, a session context and its beans exist during the lifetime of an HTTP session. Injected references to the beans are contextually aware.
Weld is the reference implementation of CDI: Contexts and Dependency Injection for the Java EE Platform - a JCP standard for dependency injection and contextual lifecycle management and one of the most important and popular parts of the Java EE.
A CDI bean is a POJO, plain old java object, that has been automatically instantiated by the CDI container, and is injected into all, and any qualifying injection points in the application. The CDI container initiates the bean discovery process during deployment.
The request scope creates a bean instance for a single HTTP request, while the session scope creates a bean instance for an HTTP Session. The application scope creates the bean instance for the lifecycle of a ServletContext, and the websocket scope creates it for a particular WebSocket session.
There is a possibility you need to create Request or Session context your self.
That is of course CDI implementation and application specific.
For example, if you use Weld and need Request Scope, you can create and activate org.jboss.weld.context.bound.BoundRequestContext.
/* Inject the BoundRequestContext. */
/* Alternatively, you could look this up from the BeanManager */
@Inject BoundRequestContext requestContext;
...
/* Start the request, providing a data store which will last the lifetime of the request */
public void startRequest(Map<String, Object> requestDataStore) {
// Associate the store with the context and activate the context
requestContext.associate(requestDataStore);
requestContext.activate();
}
/* End the request, providing the same data store as was used to start the request */
public void endRequest(Map<String, Object> requestDataStore) {
try {
/* Invalidate the request (all bean instances will be scheduled for destruction) */
requestContext.invalidate();
/* Deactivate the request, causing all bean instances to be destroyed (as the context is invalid) */
requestContext.deactivate();
} finally {
/* Ensure that whatever happens we dissociate to prevent any memory leaks */
requestContext.dissociate(requestDataStore);
}
}
you can found info and this Example here https://docs.jboss.org/weld/reference/latest/en-US/html/contexts.html
Also for BoundConversationContext. Session scope is little bit harder, you need a real session support in your application to be able to implement it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With