【问题标题】:Why my stateless session bean works as stateful? [duplicate]为什么我的无状态会话 bean 是有状态的? [复制]
【发布时间】:2017-09-15 18:51:45
【问题描述】:

我已经编写了有状态会话 bean:

@Stateful
public class SessionBean {
List<Integer> list = new ArrayList<>();
public void addItem(int s) {
    list.add(s);
}
public int getItemsCount() {
    return list.size();
}
}

并在我的 servlet 中使用它:

@WebServlet("/add")
public class AddServlet extends HttpServlet {
@Inject
SessionBean sessionBean;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    int i = sessionBean.getItemsCount();
    resp.getWriter().write(i + " ");
    sessionBean.addItem(i + 1);
}
}

它按预期工作,列表保存状态,我可以在下一个请求中使用它。 但是,如果我在@Stateless 上更改@Stateful,我希望不存储bean 的状态,并进入每个请求的干净列表,但它总是保存先前请求的状态并显示新的数字。那么无状态和有状态有什么区别呢?怎么看?如我所见,它们的工作方式相同。 我想看到一个例子,它会显示类似的东西——这里我们使用有状态的,它保存状态,在这里我们改变无状态,它的工作方式不同,而不是保存状态。请告诉我不同​​之处。

【问题讨论】:

  • Web servlet 正在存储会话 bean 的状态。如果每个会话都需要一个新的SessionBean,则必须手动创建它并将其存储在 http 会话中。更多信息请参考this thread
  • 见过一些情况,其中 SLSB 的行为类似于 SFSB。 IE SLSB 注入单例。在这种情况下,使用了相同的 SLSB 实例。我相信在您的情况下,同一个 bean 实例也已从池中重用。您是否尝试过多次并发调用 servlet URL?我相信如果你这样做了,这种伪状态效应就不会再出现了。

标签: java ejb stateless stateful


【解决方案1】:

无状态会话 bean 不应携带任何形式的状态,例如实例变量。因此,容器通常会维护一个无状态 bean 池,以便它们可以被不同的客户端重用。

Oracle 文档提到以下有关会话 bean 的内容:http://docs.oracle.com/javaee/5/tutorial/doc/bnbly.html

但是,客户端可能会更改池化无状态 bean 中实例变量的状态,并且此状态会保留到池化无状态 bean 的下一次调用。

您可能会遇到这种现象,以及为什么列表不为空。

【讨论】:

    【解决方案2】:

    但如果我在 @Stateless 上更改 @Stateful 我希望不存储 bean 的状态,并进入每个请求的清理列表,但它总是保存先前请求的状态并显示新的数字。

    有状态与无状态的区别主要是声明性的,而不是功能性的。如果您将会话 bean 声明为无状态,则有责任确保它在方法调用之间实际上不保留任何状态。

    那么无状态和有状态有什么区别呢?怎么看?如我所见,它们的工作原理相同。

    其中一个更重要的区别是,如果您声明一个 bean 无状态,那么您可以为容器提供使用不同 bean 实例服务不同请求的选项。如果它选择这样做,那么这可能会使实际上保留状态的声明无状态 bean似乎毕竟不保留状态,至少在有限的范围内。但是容器不需要这样做,所以如果你的无状态 bean 通过保留状态违反了它的合同,那么这可能迟早会被客户看到。

    还有更多(实际上更多——阅读the specifications),但最重要的是我带头的东西。换句话说,将会话 bean 正确声明为无状态与有状态是其开发人员与部署它的容器签订的合同的一部分。 bean 的行为与其代码要求的行为并无不同,只是因为它被声明为无状态。

    【讨论】:

    • 嗯,在某些情况下,bean 的行为会有所不同,例如,对于使用 BMT 的无状态,您必须在方法返回之前提交事务,而有状态的可以让事务保持打开并提交在稍后阶段使用完全不同的方法。
    • 这是一个公平的观点,@Leonardo。也完全符合这个答案,没有试图列举无状态和有状态bean之间的所有差异,并且确实明确观察到还有其他差异。
    猜你喜欢
    • 2016-04-14
    • 1970-01-01
    • 1970-01-01
    • 2013-02-22
    • 2014-06-23
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多