为什么我的无状态会话bean作为statefull工作?

时间:2017-04-19 13:40:44

标签: java ejb stateless stateful

我写了有状态会话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的状态,并获取每个请求清单,但它总是保存先前请求的状态并显示新的数字。那么无国籍和有状态有什么区别?怎么看?正如我所见,他们的工作方式相同。 我想看看会显示类似的例子 - 这里我们使用有状态并保存状态,这里我们改变无状态,它的工作方式不同而不保存状态。请告诉我差异。

2 个答案:

答案 0 :(得分:1)

  

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

Stateful vs. Stateless的区别首先是声明性的,而不是功能性的。如果您声明会话bean是无状态的,那么您的责任是确保它实际上不会在方法调用之间保留任何状态。

  

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

更重要的一个区别是,如果您声明bean无状态,那么您可以为容器提供使用不同bean实例提供不同请求的选项。如果它选择这样做那么那可能会使一个声明无状态的bean实际上保持状态出现而不是至少保留状态,至少在一定程度上。但是容器不需要这样做,所以如果你的无状态bean通过保留状态违反了它的合同,那么迟早可能会让客户看到它。

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

答案 1 :(得分:1)

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

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

  

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

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