2012-12-16 4 views
0

Stateful Session Bean을 사용하여 EJB 3.1을 프로그래밍하려고합니다. EJB가 무엇인지, 상태 저장, 상태 저장 및 싱글 톤의 차이점을 잘 이해해야합니다.EJB 3.1 Stateful Bean은 Singleton Bean처럼 동작합니다.

그러나 내 stateful bean에는 이상한 동작이 있습니다. 그것은 싱글 톤처럼 행동합니다! 내말은 여러 클라이언트/브라우저/머신에서 아래 서블릿 (ShoppingCartServlet)을 호출하면 같은 빈이 반환되고 매번 같은 값이 증가합니다. "count"값은 bean이 싱글 톤이기 때문에 클라이언트로부터 공유됩니다.

제발, 이해하겠습니다!

여기 코드입니다.

서블릿 코드

@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; 
    } 
} 

서블릿을 WAR 파일로 패키지 및 JAR 파일의 EJB. 둘 다 고유 한 EAR 파일에 배치됩니다.

편집 : 아래와 같이 내 서블릿 코드를 변경하려고했지만 모든 호출시에 새로운 Stateful 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); 
} 
+0

아마도 서블릿 대신 JAX-RS를 사용할 수 있습니까? –

답변

2

여러 요청에 대해 동시에 재사용되는 서블릿 인스턴스가 하나 있습니다. 그래서, 그것은 주입 된 동일한 상태 유지 콩이고, 모든 요청에 ​​의해 공유되고 있습니다.

서블릿의 스레드 안전성을 위해 인스턴스 변수 대신 로컬 변수를 사용하는 것이 좋습니다. 따라서 클래스 수준에서 주입하는 대신 메서드에서 빈을 조회 할 수 있습니다.


편집 :

당신은 미래 활동에 대한 HttpSession 객체 검색을 통해 얻은 EJB 인스턴스를 저장할 수 있습니다. 따라서 동일한 인스턴스가이 방법을 통해 &을 얻을 때마다 재사용하지 않고 대화 상태가 유지됩니다.

+1

나는 스테이트 풀 세션 빈을 스테이트리스 오브젝트 (서블릿, 스테이트리스 세션 빈 등)에 주입하는 것은 결코 좋은 생각이 아니다. –

+0

@bkail 추가 설명 주셔서 감사합니다 –

+0

doGet() 서블릿 메소드에서 코드를 변경했지만 지금은 모든 호출마다 새로운 Stateful Bean이 작성되었습니다. (자세한 내용은 아래 내 의견을 참조하십시오.) – nuno

관련 문제