【问题标题】:Why Stateful and Stateless beans behave in opposite way?为什么有状态和无状态 bean 的行为方式相反?
【发布时间】:2016-09-08 11:58:06
【问题描述】:

我创建了有状态、无状态和单例 bean 类,并尝试访问它们两个不同的 servlet。并在 JBoss 服务器上运行项目。

当我从每个 servlet 访问有状态 bean 时,将创建两个不同的 bean 对象,并为它们保留不同的状态(数据)。但是无状态 bean 对象在两个 servlet 之间共享。单例 bean 的行为方式也与无状态 bean 相同。

我的问题是为什么有状态和无状态 bean 的行为方式相反? session bean的生命周期和servlet的生命周期一样吗?

FirstServlet.java

@WebServlet("/FirstServlet")
public class FirstServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

@EJB
StatelessBean statelessBean;

@EJB
StateFullBean statefulBean;

@EJB
SingletonBean singletonBean;

protected void doPost(HttpServletRequest request,
        HttpServletResponse response) throws ServletException, IOException {
    String message = "Beans not injected.";

    String beanType = request.getParameter("beanType");

    if ("Stateless".equals(beanType)) {
        if (statelessBean != null) {
            message = statelessBean.getHits();
        } else {
            message = "Stateless bean not injected.";
        }
    }

    if ("Stateful".equals(beanType)) {
        if (statefulBean != null) {
            message = statefulBean.getHits();
        } else {
            message = "Stateful bean not injected.";
        }
    }

    if ("Singleton".equals(beanType)) {
        if (singletonBean != null) {
            message = singletonBean.getHits();
        } else {
            message = "Singleton bean not injected.";
        }
    }

    response.setContentType("text/html");
    response.getWriter().print("<h1>" + message + "</h1>");
}
}

同样,我又创建了一个 servlet DemoServlet.java。

StateFullBean.java

@Stateful
public class StateFullBean{

int hits=0;

public String getHits() {
    hits++;
    return "StateFullBean number of hits " + hits;
}

public StateFullBean() {
    System.out.println("StateFullBean created.");
}
}

StatelessBean.java

@Stateless
public class StatelessBean{

int hits=0;

public String getHits() {
    hits++;
    return "StatelessBean number of hits " + hits;
}

public StatelessBean() {
    System.out.println("StatelessBean created.");
}
}

SingletonBean.java

@Startup
@Singleton(name="SingletonBean")
public class SingletonBean {

int hits=0;

public SingletonBean() {
    System.out.println("SingletonBean created.");
}

public String getHits() {
    hits++;
    return "Singleton bean number of hits " + hits;
}
}

我是否遗漏了代码中的某些内容?

【问题讨论】:

    标签: ejb


    【解决方案1】:

    一切都按规定进行。

    无状态 EJB 将调用进一步委托给池中当前可用的实例。显然只有一个没有同时使用(还),因此所有客户端都有相同的机会访问池中的同一个实例。如果您在 servlet 上同时触发更多 HTTP 请求,则不再有可用实例的可能性会增加,并且容器将在池中创建一个新实例。

    有状态的 EJB 绑定到它的客户端(在您的例子中,是 web servlet 实例)。换句话说,每个 servlet 都有自己的有状态 EJB 实例,不会在其他地方共享。

    单例 bean 是应用程序范围的,并在所有客户端之间共享。换句话说,每个 servlet 将共享同一个单例 EJB 实例。

    请注意,EJB 上下文中的术语“客户端”和“会话”绝对不与 WAR 上下文中的术语相同,这是许多初学者失败的地方。 EJB 客户端不是 Web 浏览器,而是注入 EJB 的类的实例(在您的情况下,是 Web servlet 实例)。 EJB 会话不是 HTTP 会话,而是 EJB 客户端会话。

    另见:

    【讨论】:

      猜你喜欢
      • 2016-04-14
      • 2013-02-22
      • 2010-12-16
      • 1970-01-01
      • 2017-09-15
      • 2015-05-09
      • 2022-12-16
      • 1970-01-01
      相关资源
      最近更新 更多