【问题标题】:How does CDI remove stateful session bean?CDI 如何删除有状态会话 bean?
【发布时间】:2012-05-11 07:46:56
【问题描述】:

规范说,当作用域的上下文即将被销毁时,CDI 容器会删除 SFSB。它如何准确地删除 EJB?它似乎没有调用带有@Remove 注释的方法。

@Stateful
public class CustomerDAOImpl implements CustomerDAO {
    @PreDestroy
    public void onDestroy() {
        //This is getting called as expected
    }
    @Remove
    public void deleteMyBean() {
        //This is not getting called!
    }
}

因此,CDI 在技术上按照规范执行。问题是如何要求 EJB 容器移除实例?谢谢。

【问题讨论】:

    标签: cdi ejb-3.1


    【解决方案1】:

    正如 covener 所说,这是使用特定于实现的 EJB API 完成的,这不是 EJB 标准 API 的一部分。

    正如 covener 所说,调用 @Remove 不是正确的方法。 @Remove 方法由用户代码调用,并告诉 EJB 容器删除EJB。如果您想在删除 EJB 时进行回调,请使用 @PreDestroy。

    【讨论】:

      【解决方案2】:

      我认为 CDI 容器需要一个钩子到 EJB 容器中,以要求它“做你会做的事情,如果 @Remove 方法刚刚完成”。查看 EJB 规范,EJB 2.1 在您必须扩展的接口中为此提供了一种机制。

      出于显而易见的原因,不建议容器调用任意的 @Remove 注释方法来获得副作用。

      【讨论】:

      • +1,但是作为一个nit,容器拥有EJBObject的实现(有.remove,这基本上是CDI想要使用的),但是bean实现了SessionBean。
      • 这不是一个答案,而是一个猜测。如果确实有这样的钩子,它将是高度特定于供应商的。像 Weld 这样的实现如何以通用方式做到这一点。
      • 问题不在于 Weld 是否可移植。 Weld 特别要求容器提供各种接口的实现,包括 SessionObjectReference#remove
      【解决方案3】:

      带有@Remove注解的方法必须被客户端显式调用,然后容器将隐式调用带有@PreDestroy注解的方法,如果存在的话。之后,bean 实例就可以进行垃圾回收了。

      这是客户端可以控制的唯一生命周期方法,所有其他方法都由容器控制。

      【讨论】:

      • 是的,这是正常行为。但是 CDI 容器是如何移除 EJB 的呢?是否使用某种未记录的 API 要求 EJB 容器进行删除?
      • @RajV 我无法在规范中找到它,但您可以在 Java EE 教程中找到有用的信息,在The Life Cycle of a Stateful Session Bean 会话docs.oracle.com/javaee/5/tutorial/doc/bnbmt.html
      猜你喜欢
      • 1970-01-01
      • 2014-06-24
      • 2014-12-26
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      • 1970-01-01
      • 1970-01-01
      • 2014-12-18
      相关资源
      最近更新 更多