1

私はEJBを初めて使用します。EARアプリケーションにステートフルBeanが必要です。ejbモジュールで単純なステートフルセッションBeanを作成しました。

@Stateful
public class Test {

    public Test() {
    }

    private int i;

    @PostConstruct
    public void initialize() {
        i = 0;
    }

    public int getI() {
        return i++;
    }
}

そして、warモジュールのサーブレットから呼び出します。

public class TestServlet extends HttpServlet {

    @EJB
    Test test;

    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        HttpSession session = request.getSession(true);

        out.println("<html>");
        out.println("<head>");
        out.println("<title></title>");            
        out.println("</head>");
        out.println("<body>");
        out.println("<h1>" + test.getI() + "</h1>");
        out.println("</body>");
        out.println("</html>");         
        out.close();
    }
...
}

実行すると、ブラウザを更新するたびに数値が大きくなります。

0、1、2、..。

しかし、別のブラウザで実行すると、番号は0から始まりませんが、前のブラウザからのセッションを継続します。シングルトンのように動作します。

3、4、5、..。

Beanの新しいインスタンスが作成されなかったのはなぜですか?セッションBeanをwarモジュールに入れるか、SessionScopedで注釈を付けようとしましたが、結果は同じです。

httpセッションごとにステートフルBeanの新しいインスタンスを作成するのを手伝ってもらえますか?

4

1 に答える 1

4

すべてのリクエストを処理するために、単一のサーブレットが作成されます。単一のステートフルセッションBeanのインスタンスをサーブレットに注入しているため、すべてのリクエストで同じステートフルセッションBeanが使用されます。ステートフルセッションBeanを注入することが役立つことはめったにありません。

ステートフルセッションBeanのHttpSessionごとのインスタンスを作成する必要があります。

// Declare the reference without injection...
@EJB(name="ejb/test" beanInterface=Test.class)
public class TestServlet extends HttpServlet {
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();

        HttpSession session = request.getSession(true);
        Test bean = session.getAttribute(BEAN);
        if (bean == null) {
            try {
                // ...and then create an instance by looking it up from java:comp/env
                bean = (Test)new InitialContext().lookup("java:comp/env/ejb/test");
            } catch (NamingException ex) { ... }
            session.setAttribute(BEAN, bean);
        }

        ...
    }
}

または、CDIがある場合は、ステートフルセッションBeanを@SessionScopedとしてマークし、@EJBではなく@Injectをインジェクションに使用できます。

于 2012-04-26T14:20:22.603 に答える