Using a Stateful Session Bean

There are a few basic things to keep in mind when working with stateful session beans:


   1.      When a client obtains a reference to a stateful session bean, a private instance of that bean is created for the client. In other words, there is one bean instance per client reference.

 

   2.      The bean does not go away until the client invokes a method annotated with @Remove. If the client forgets or is unable to end the conversation with the bean, it will hang around until the server can determine that it is safe to remove it.

 

   3.      A reference to a stateful session bean cannot be shared between threads.

A consequence of these rules is that clients need to plan carefully on when they need to start the session and when it can be ended. It also means that using the @EJB annotation to inject a stateful session bean is not a good solution. Servlets, stateless session beans, and message-driven beans are all stateless components. As we stated before in the description of stateless session beans, that means that any state placed on a stateless component must also be stateless as well. A stateful session bean reference is itself stateful because it references a private instance of the bean managed by the server. If @EJB were used to inject a stateful session bean into a stateless session bean where the server had pooled 100 bean instances, then there would be 100 stateful session bean instances created as well. The only time it is ever safe to inject a stateful session bean is into another stateful session bean.

Dependency lookup is the preferred method for acquiring a stateful session bean instance for a stateless client. The EJBContext lookup() method is the easiest way to accomplish this, but JNDI will be required if the client is a servlet. Listing 3-23 demonstrates a typical pattern for servlets using stateful session beans. A reference is declared to the bean, it is looked up lazily when needed, and the result is bound to the HTTP session. The stateful session bean and HTTP session have similar life cycles, making them good candidates to work together.

 

Listing 3-23: Creating and Using a Stateful Session Bean

 

@EJB(name="cart", beanInterface=ShoppingCart.class)
public class ShoppingCartServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        HttpSession session = request.getSession(true);
        ShoppingCart cart = (ShoppingCart) session.getAttribute("cart");
        if (cart == null) {
            try {
                Context ctx = new InitialContext();
                cart = (ShoppingCart) ctx.lookup("java:comp/env/cart");
                session.setAttribute("cart", cart);
            } catch (NamingException e) {
                throw new ServletException(e);
            }
        }

        if (request.getParameter("action").equals("add")) {
            String itemId = request.getParameter("item");
            String quantity = request.getParameter("quantity");
            cart.addItem(itemId, Integer.parseInt(quantity));
        }
        if (request.getParameter("action").equals("cancel")) {
            cart.cancel();
            session.removeAttribute("cart");
        }

        // ...
    }
}

When the server receives a request to look up a stateful session bean, it asks the EJB container to create a new instance of the bean, which is then assigned a unique identifier. The reference to the bean that is returned keeps track of this identifier and uses it when communicating with the server to ensure that the right bean instance is used to invoke each business method.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值