当 bean=null 时,应用服务器是否丢弃有状态 bean 实例并创建新实例?

When bean=null, does the app server trash the stateful bean instance and create new one?

我知道这个问题已经被问了上百万次了,但到目前为止它并没有回答我脑海中的问题,我认为最好用代码来理解,有人可以验证我的想法吗:

客户端中的无状态 bean:

public void work(){
    bean.work1();   <--- this uses instance 1 in App Server
    ...
    bean.work2();   <--- this can be instance 2 in App Server
}

客户端中的有状态 bean:

public void work(){
    bean.add_item(item); <------- this uses instance 1 in App Server
    ....
    bean.checkout();     <------- this uses instance 1 in App Server
}

销毁会话:

public void work(){
    ...
    bean = null;
}

来自 Oracle 文档

As its name suggests, a session bean is similar to an interactive session. A session bean is not shared; it can have only one client, in the same way that an interactive session can have only one user. When the client terminates, its session bean appears to terminate and is no longer associated with the client.

The state is retained for the duration of the client/bean session. If the client removes the bean, the session ends and the state disappears. This transient nature of the state is not a problem, however, because when the conversation between the client and the bean ends, there is no need to retain the state

如果以上是正确的,我从中得出的问题是,当 bean 引用设置为 null 时,App 服务器是否会丢弃有状态 bean 实例并创建新实例?我问这是因为:

  1. 我们向 bean 添加了项目,并且将继续为新客户使用 bean,除非我们实现 flush 方法,但我认为这不是正确的方法。
  2. 如果在最佳实践中 bean 不应该改变它自己的状态,即向 bean 内部的 this.items 添加项目,我想不出为什么要使用有状态 bean 的更好理由?
  3. “状态”是指 bean 实例本身吗?

您对哪些 bean 实例可用于 stateless/stateful 会话 bean 的分析是正确的。

将字段设置为 null 并没有真正做任何事情。要销毁有状态会话 bean,您需要调用 remove 方法(如果您使用的是 EJB 3,这意味着调用注释为 @Remove)的方法。

  1. 如果您指的是无状态会话 bean,则根本不应将状态存储在 bean 中。如果您指的是有状态会话 bean,则 flush 方法似乎是合理的,或者您可以将逻辑放在 @Remove 方法(可能命名为 flush)中。

  2. 改变状态就可以了。你是对的,保持状态是有状态会话 bean 的意图。

  3. 是的,但也意味着与客户端的关联。无状态会话 bean 可以清楚地将状态存储在成员变量中,但由于不能保证客户端获得相同的实例,因此 EJB(不是实例)没有真实状态。这也意味着无状态会话 bean 不应将客户端状态存储在成员变量中,因为没有实际用途。