Programing

Stateless 및 Stateful Enterprise Java Bean

lottogame 2020. 9. 8. 21:51
반응형

Stateless 및 Stateful Enterprise Java Bean


Java EE 6 튜토리얼을 진행 중이며 Stateless와 Stateful 세션 Bean의 차이점을 이해하려고합니다. Stateless Session Bean이 메소드 호출 사이에 상태를 유지하지 않는 경우 내 프로그램이 그대로 작동하는 이유는 무엇입니까?

package mybeans;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

@LocalBean
@Stateless
public class MyBean {

    private int number = 0;

    public int getNumber() {
        return number;
    }

    public void increment() {
        this.number++;
    }
}

클라이언트

import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;
import mybeans.MyBean;
import java.io.PrintWriter;

@WebServlet(name = "ServletClient", urlPatterns = { "/ServletClient" })
public class ServletClient extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @EJB
    MyBean mybean;

    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        mybean.increment();
        out.println(mybean.getNumber());
    }

}

getNumber가 매번 0을 반환 할 것으로 예상했지만 1을 반환하고 브라우저에서 서블릿을 다시로드하면 더 많이 증가합니다. 문제는 물론 라이브러리 나 애플리케이션 서버가 아닌 상태 비 저장 세션 빈이 어떻게 작동하는지에 대한 나의 이해에 있습니다. 누군가가 stateful로 변경할 때 다르게 동작하는 stateless 세션 빈의 간단한 hello world 유형 예제를 줄 수 있습니까?


중요한 차이점은 개인 멤버 변수가 아니라 상태를 특정 사용자와 연관시키는 것입니다 (예 : "장바구니").

The stateful piece of stateful session bean is like the session in servlets. Stateful session beans allow your app to still have that session even if there isn't a web client. When the app server fetches a stateless session bean out of the object pool, it knows that it can be used to satisfy ANY request, because it's not associated with a particular user.

A stateful session bean has to be doled out to the user that got it in the first place, because their shopping cart info should be known only to them. The app server ensures that this is so. Imagine how popular your app would be if you could start shopping and then the app server gave your stateful session bean to me when I came along!

So your private data member is indeed "state", but it's not "shopping cart". Try to redo your (very good) example to make it so the incremented variable is associated with a particular user. Increment it, create a new user, and see if they can still see the incremented value. If done correctly, every user should see just their version of the counter.


Stateless Session Beans (SLSB) are not tied to one client and there is no guarantee for one client to get the same instance with each method invocation (some containers may create and destroy beans with each method invocation session, this is an implementation-specific decision, but instances are typically pooled - and I don't mention clustered environments). In other words, although stateless beans may have instance variables, these fields are not specific to one client, so don't rely on them between remote calls.

In contrast, Stateful Session Beans (SFSB) are dedicated to one client for their entire life, there is no swapping or pooling of instances (it may be evicted from memory after passivation to save resources but that's another story) and maintain conversational state. This means that the instance variables of the bean can keep data relative to the client between method invocations. And this makes possible to have interdependent method calls (changes made by one method affect subsequent method calls). Multi-step processes (a registration process, a shopping cart, a booking process...) are typical use cases for SFSB.

One more thing. If you are using SFSB, then you must avoid injecting them into classes that are multithreaded in nature, such as Servlets and JSF managed beans (you don't want it to be shared by all clients). If you want to use SFSB in your web application, then you need to perform a JNDI lookup and store the returned EJB instance in the HttpSession object for future activity. Something like that:

try {
    InitialContext ctx = new InitialContext();
    myStateful = (MyStateful)ctx.lookup("java:comp/env/MyStatefulBean");
    session.setAttribute("my_stateful", myStateful);
} catch (Exception e) {
    // exception handling
}

Stateless and stateful in this context don't mean quite what you might expect.

Statefulness with EJBs refers to what I call conversational state. The classic example is a flight booking. If it consists of three steps:

  • Reserve seat
  • Charge credit card
  • Issue Ticket

Imagine each of those is a method call to a session bean. A stateful session bean can maintain this kind of conversation so it remembers what happens between calls.

Stateless session beans don't have such capacity for conversational state.

Global variables inside a session bean (stateless or stateful) are something else entirely. Stateful session beans will have a pool of beans created (since a bean can only be used in one conversation at a time) whereas stateless sesion beans will often only have one instance, which will make the global variable works, but I don't think this is necessarily guaranteed.


This thing happen because the container only has one bean instance in the pool that is being reused for all calls. If you run the clients in parallel you will see a different result because the container will create more bean instances in the pool.


It has good answers. I would like to add small answer. Stateless Bean should not used to hold any client data. It should be used to "to model actions or processes that can be done in one shot".


The major differences between the two major types of session beans are:

Stateless Beans

  1. Stateless Session Beans are the ones which have no conversational state with the client which has called its methods. For this reason they can create a pool of objects which can be used to interact with multiple clients.
  2. Performance wise stateless beans are better since they don't have states per client.
  3. They can handle multiple requests from multiple clients in parallel.

Stateful Beans

  1. Stateful session beans can maintain the conversational state with multiple clients at a time and the task is not shared between the clients.
  2. After the session is completed the state is not retained.
  3. The container can serialize and store the state as a stale state for future use. This is done to save resources of the application server and to support bean failures.

Good Question,

try this code (change MyBean Stateful/Stateless.):

import javax.ejb.LocalBean;
import javax.ejb.Stateful;
import javax.ejb.Stateless;

@LocalBean 
@Stateless 
public class MyBean {

    private int number = 0;

    public int getNumber() {
        return number;
    }

    public void increment() {
        this.number++;
    }
}

Servlet_1

 import java.io.IOException;
    import javax.ejb.EJB;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import javax.servlet.annotation.WebServlet;

    import java.io.PrintWriter;

    @WebServlet(name = "ServletClient", urlPatterns = { "/ServletClient" })
    public class ServletClient extends HttpServlet {

        private static final long serialVersionUID = 1L;

        @EJB
        MyBean mybean;

        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

            PrintWriter out = response.getWriter();
            mybean.increment();
            out.println(mybean.getNumber());
        }

    }

Servlet_2

import java.io.IOException;
import javax.ejb.EJB;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;

import java.io.PrintWriter;

@WebServlet(name = "NewServletClient", urlPatterns = { "/NewServletClient" })
public class NewServletClient extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @EJB
    MyBean mybean;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        PrintWriter out = response.getWriter();
        mybean.increment();
        out.println(mybean.getNumber());
    }

}

case : MyBean -@Stateless

http://localhost:8080/MYServletDemo/ServletClient

1

http://localhost:8080/MYServletDemo/ServletClient

2

http://localhost:8080/MYServletDemo_war_exploded/newServletClient

3

http://localhost:8080/MYServletDemo/ServletClient

4

case : MyBean -@Stateful

http://localhost:8080/MYServletDemo/ServletClient

1

http://localhost:8080/MYServletDemo/ServletClient

2

http://localhost:8080/MYServletDemo/newServletClient

1

http://localhost:8080/MYServletDemo/ServletClient

3

참고URL : https://stackoverflow.com/questions/2351220/stateless-and-stateful-enterprise-java-beans

반응형