Ejb 3.1 EJB3.1有状态Bean的行为类似于单例Bean

Ejb 3.1 EJB3.1有状态Bean的行为类似于单例Bean,ejb-3.1,stateful,stateful-session-bean,Ejb 3.1,Stateful,Stateful Session Bean,我正在尝试使用有状态会话bean编程EJB3.1。 我应该很好地理解EJB是什么,以及有状态、无状态和单例之间的区别 但是我的状态豆有一种奇怪的行为。它的行为就像一个单身汉!! 我的意思是,从多个客户机/浏览器/机器调用下面的servlet(ShoppingCartServlet),返回相同的bean,并且每次都递增相同的值。 “count”值是从客户端共享的,因为bean是单例的 请帮我理解 这是代码 Servlet代码 @WebServlet(name=“ShoppingCartServle

我正在尝试使用有状态会话bean编程EJB3.1。 我应该很好地理解EJB是什么,以及有状态、无状态和单例之间的区别

但是我的状态豆有一种奇怪的行为。它的行为就像一个单身汉!! 我的意思是,从多个客户机/浏览器/机器调用下面的servlet(ShoppingCartServlet),返回相同的bean,并且每次都递增相同的值。 “count”值是从客户端共享的,因为bean是单例的

请帮我理解

这是代码

Servlet代码

@WebServlet(name=“ShoppingCartServlet”,urlPatterns=“/shoppingCart”)
公共类ShoppingCartServlet扩展了HttpServlet{
私有静态最终长serialVersionUID=2789580260930727133L;
@EJB
私人购物车;
@凌驾
受保护的void doGet(HttpServletRequest请求,HttpServletResponse响应)抛出ServletException,IOException{
int count=shoppingCart.increaseCount();
HttpSession session=request.getSession();
session.setAttribute(“count”,count);
字符串nextJSP=“/shoppingCart.jsp”;
RequestDispatcher dispatcher=getServletContext().getRequestDispatcher(nextJSP);
转发(请求、响应);
}
}
EJB代码

@Stateful
@本地豆
公共类购物车{
私人整数计数;
公共整数递增计数(){
计数++;
返回计数;
}
}
Servlet打包在WAR文件中,EJB打包在JAR文件中。两者都部署在一个唯一的EAR文件中

Edit:我试图更改我的servlet代码,如下所示,但现在每次调用都会创建一个新的有状态Bean

受保护的void doGet(HttpServletRequest请求,HttpServletResponse响应)抛出ServletException,IOException{
Context ctx=新的InitialContext();
ShoppingCart ShoppingCart=(ShoppingCart)ctx.lookup(“java:global/jeeapp/jeeapp business/ShoppingCart!org.madbit.jeeapp.shopping.ejb.ShoppingCart”);
int count=shoppingCart.increaseCount();
HttpSession session=request.getSession();
session.setAttribute(“count”,count);
字符串nextJSP=“/shoppingCart.jsp”;
RequestDispatcher dispatcher=getServletContext().getRequestDispatcher(nextJSP);
转发(请求、响应);
}

有一个servlet实例可同时用于多个请求。因此,注入的是同一个有状态bean,被所有请求共享

对于servlet中的线程安全,最好使用局部变量,而不是实例变量。所以,您可以在方法中查找bean,而不是在类级别进行注入


编辑:


您可以将通过查找获得的EJB实例存储在
HttpSession
对象中,以备将来使用。因此,同一个实例将被重用,而不是每次都获得它&通过这种方式,会话状态将得到维护。

我将给出一个更强烈的建议:将有状态会话bean注入无状态对象(servlet、无状态会话bean等)从来都不是一个好主意@bkail感谢您的进一步澄清。我已经更改了我的代码,在doGet()servlet方法中放置了一个查找,但是现在我的代码在每次调用中都会创建一个新的有状态Bean。(有关更多详细信息,请参见下面我的评论)也许更容易向您解释我将要做的事情,即在同一会话中的几个jsp页面上增加一个计数器(在有状态bean中)。@Supertramp请不要添加信息作为答案,而是更新原始帖子。另外,我已经更新了答案,请参考其中的编辑部分。也许您可以使用JAX-RS而不是servlet?