EJB 3.1 有状态 Bean 的行为类似于 Singleton Bean



我正在尝试使用有状态会话 bean 编写 EJB 3.1。我应该很清楚什么是 EJB 以及有状态、无状态和单例之间的区别。

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

请帮我理解!!

这里是代码。

Servlet 代码

@WebServlet(name="ShoppingCartServlet", urlPatterns="/shoppingCart")
public class ShoppingCartServlet extends HttpServlet {
    private static final long serialVersionUID = 2789580260930727133L;
    @EJB 
    private ShoppingCart shoppingCart;
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        int count = shoppingCart.increaseCount();
        HttpSession session = request.getSession();     
        session.setAttribute("count", count);
        String nextJSP = "/shoppingCart.jsp";
        RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextJSP);       
        dispatcher.forward(request, response);
    }
}

EJB 代码

@Stateful
@LocalBean
public class ShoppingCart {
    private int count;  
    public int increaseCount() {
        count++;
        return count;
    }
}

Servlet 打包在 WAR 文件中,EJB 打包在 JAR 文件中。两者都部署在唯一的 EAR 文件中。

编辑:我试图像下面这样更改我的servlet代码,但现在每次调用都会创建一个新的有状态Bean。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Context ctx = new 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);
    String nextJSP = "/shoppingCart.jsp";
    RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(nextJSP);       
    dispatcher.forward(request, response);
}

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

最好

在 servlet 中使用局部变量而不是实例变量来实现线程安全。因此,您可以在方法中查找 bean,而不是在类级别注入。


编辑:

您可以将通过查找获得的 EJB 实例存储在 HttpSession 对象中,以供将来活动使用。因此,相同的实例将被重用,而不是每次都获取它,通过这种方式,会话状态将被保持。

最新更新