我创建了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;
}
}
我错过了代码中的内容吗?
答案 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客户端会话。