无法在 HttpSessionListener 中注入 CDI @SessionScoped

Cannot inject CDI @SessionScoped in HttpSessionListener

我有一个有状态的会话范围 (CDI) EJB,它保存有关用户会话的信息。

@Stateful
@SessionScoped
public class GestorSesion implements IGestorSesionLocal, Serializable {

  private final static long serialVersionUID = 1L;

  private static final Logger log = Logger.getLogger(GestorSesion.class.getName());

  @PostConstruct
  private void init() {
    log.info("Configurando información de usuario");
    log.info("****************************************************************************");
  }

  @Override
  public void cerrarSesion() {
  }

  @Override
  public ISessionInfo getSesionInfo() {
    return null;
  }
}

现在,我想从 HttpSessionListener

调用 cerrarSesion() (closeSession())
public class GestorSesionWeb implements HttpSessionListener {


  private static final Logger log = Logger.getLogger(GestorSesionWeb.class.getName());

  @Inject
  private Instance<IGestorSesionLocal> gestorSesion;

  @Override
  public void sessionCreated(HttpSessionEvent se) {
    if (log.isLoggable(Level.FINE)) {
      log.fine("Iniciada sesión web");
    }
    gestorSesion.get().getSesionInfo();
  }

  @Override
  public void sessionDestroyed(HttpSessionEvent se) {
    if (log.isLoggable(Level.FINE)) {
      log.fine("Limpiando sesión al salir");
    }
    try {
      this.gestorSesion.get().cerrarSesion();
      if (log.isLoggable(Level.FINE)) {
        log.fine("Sesión limpiada sin problemas");
      }
    } catch (Exception e) {
      log.log(Level.WARNING, "Excepción limpiando sesión", e);
    }
  }
}

然后我从 webapp 访问 EJB,直接(使用 @EJB 注入)到我用于 JSF 的 bean(它们也是 CDI 管理的 bean)中。

我面临的问题是 HttpSessionListener 似乎与 JSF bean 在不同的 "session scope" 中。 GestorSession 的两个实例被创建;一个从 JSF 实例化,另一个从 HttpSessionListener 实例化。

我尝试通过 @Inject Instance<IGestorSesionLocal>@Inject IGestorSesionLocalBeanManager 注入 bean,结果相同。

This bug report 建议它应该可以正常工作(我的版本已解决该错误),但我仍然无法解决它。我环顾四周,但我发现的是与 JSF 托管 bean 相关的问答(是的,我可以尝试在 JSF 托管 bean 中包装对 EJB 的引用,但我想先尝试一下 "correctly")。

使用 Wilfly 8.1.0 和 JDK 7

有什么想法吗?

我认为你的 pb 来自这里:

And I access the EJB from the webapp, directly (injecting using @EJB) into the JSF beans.

当将 CDI 与 EJB 一起使用时(例如,通过在其上放置 @Sessionscoped),您将获得一个也具有 EJB 性质的 CDI bean,但反之则不然。换句话说,CDI 知道 EJB 的本质,但 EJB 不知道 CDI。

因此,如果您想在代码中将 EJB 作为 CDI bean 注入,请使用 @Inject 而不是 @EJB。从 Java EE 6 开始,公认的良好做法是始终使用 @Inject 除了 EJB 远程。

还要确保仅使用 CDI 托管 bean,而不是混合使用 CDI 和 JSF 托管 bean。