ContextNotActiveException

ContextNotActiveException

我们希望使用CDI来实现一些交叉功能,例如记录审核信息,授权等。为此,我们需要一些bean,其中包含当前用户的注入点,如下所示:

class AuditLogger {
  @Inject
  private Instance<User> currentUser;

  public void log(Whatever data) {
    User userWhoTriggeredIt = currentUser.get();
    ...
  }
}


此外,我们有一个会话范围内的用户管理器bean,其中包含一个生产者方法:

@SessionScoped
class UserManager {
  @Produces
  @Current
  public User getCurrentUser() {
    //get and return the user
  }
}


只要我们有一个会话上下文并且正在运行(即在我们的Web应用程序中),它就可以正常工作。但是,在某些情况下没有会话上下文,即当某些Web服务或MBean被调用时。在这种情况下,我们希望有一个备用生产者来提供通用的“应用程序”用户。

因此,基本上,在AuditLogger中,我们希望从会话范围UserManager中获取用户,除非我们在会话外部运行,在这种情况下,我们将使用后备“应用程序”用户。

但是,使用Weld 1.x似乎有点困难(我们正在JBoss 7.2中运行,并且现在无法升级,尽管我们认为如果CDI 1.2提供了解决方案)。

到目前为止,我们尝试了几种选择:


使用Instance.select( new AnnotationLiteral<Current>() {}).isUnsatisfied()检查是否有生产者。但是,这似乎返回false,因此,当我们尝试调用get()时,仍然会得到ContextNotActiveException
遍历实例(即for( User u : currentUser )),但是由于没有限定符信息,因此当我们进行会话时很难区分正确的信息(更新:测试有误导性,我们在这里也遇到了异常)
尚未尝试,但似乎有些怪异:捕获该异常并尝试后备


关于规范/最少hacky /容易出错的方法有什么想法吗?

最佳答案

Obtaining the active Context for a scope中所述,您可以编写:

@Inject
BeanManager bm;

Context context = bm.getContext(SessionScoped.class);


不幸的是,如果范围类型不存在活动上下文对象,则这仅允许检索活动上下文并抛出ContextNotActiveException异常。

因此,即使存在Context.isActive()方法,也不能不依赖ContextNotActiveException异常机制来可靠地检查上下文是否处于活动状态。

07-28 06:30