为什么有状态和无状态bean的行为方式相反?

时间:2016-05-12 14:51:11

标签: ejb

我创建了Stateful,Stateless和singleton bean类,并试图访问它们两个不同的servlet。并在JBoss服务器上运行项目。

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

我的问题是为什么有状态和无状态bean的行为方式相反?会话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;
}
}

我错过了代码中的内容吗?

1 个答案:

答案 0 :(得分:1)

一切都按照规定行事。

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

有状态EJB绑定到其客户端(在您的情况下,Web servlet实例)。换句话说,每个servlet都有自己的有状态EJB实例,而不是在其他地方共享。

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

请注意条款&#34;客户&#34;和&#34;会话&#34;在EJB上下文中绝对不是与WAR上下文中的相同,这是许多初学者失败的地方。 EJB客户端不是webbrowser,而是注入EJB的类的实例(在您的情况下,是Web servlet实例)。 EJB会话不是HTTP会话,而是EJB客户端会话。

另见: