我正在开发一个没有http接口的Java EE应用程序:它只使用MQTT来发送/接收数据。
我想知道CDI @SessionScoped
和@RequestScoped
是否适用于这种情况,或者我必须定义自定义范围来处理客户的请求。
我尝试了一个简单的应用程序,在mqtt接收回调中注入@SessionScoped
或@RequestScoped
bean,我得到一个异常,说我没有活动的上下文。
是否可以通过编程方式激活上下文,以便bean的生命周期遵循所选范围?
PS:当我发布这个问题时,我并不是太懒于进行那么简单的测试,但我很想深入研究CDI范围理论...而且我仍然是......答案 0 :(得分:5)
您可能需要自己创建请求或会话上下文。
这当然是CDI实施和特定应用。
例如,如果您使用Weld并需要Request Scope,则可以创建并激活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);
}
}
您可以在https://docs.jboss.org/weld/reference/latest/en-US/html/contexts.html
找到信息和此示例也适用于BoundConversationContext。 会话范围稍微难点,您需要在应用程序中提供真正的会话支持才能实现它。