为什么有状态和无状态的豆子以相反的方式行事? [英] Why Stateful and Stateless beans behave in opposite way?
问题描述
当我从每个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 inject。
String beanType = request.getParameter(beanType);
if(Stateless.equals(beanType)){
if(statelessBean!= null){
message = statelessBean.getHits();
} else {
message =无注入的无状态bean。
}
}
if(Stateful.equals(beanType)){
if(statefulBean!= null){
message = statefulBean。 getHits();
} else {
message =有状态bean未注入。
}
}
if(Singleton.equals(beanType)){
if(singletonBean!= null){
message = singletonBean。 getHits();
} else {
message =Singleton bean not inject。
}
}
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 ++;
returnStateFullBean命中数+命中;
}
public StateFullBean(){
System.out.println(StateFullBean created。);
}
}
StatelessBean.java / p>
@Stateless
public class StatelessBean {
int hits = 0;
public String getHits(){
hits ++;
返回StatelessBean命中数+命中;
}
public StatelessBean(){
System.out.println(StatelessBean created。);
}
}
SingletonBean.java / p>
@Startup
@Singleton(name =SingletonBean)
public class SingletonBean {
int hits = 0;
public SingletonBean(){
System.out.println(SingletonBean created。);
}
public String getHits(){
hits ++;
returnSingleton bean number of hits+ hits;
}
}
我错过了代码中的东西?
一切都符合指定。
无状态EJB将呼叫进一步委托给池中当前可用的实例。显然,只有一个不同时使用(但),因此所有客户端都有相同的机会访问池中的同一个实例。如果您在servlet上同时触发更多的HTTP请求,则可能会增加不再有可用的实例,容器将在池中创建一个新的实例。
有状态的EJB与其客户端(在您的情况下,Web servlet实例)绑定。换句话说,每个servlet都有自己的有状态的EJB实例,它不在其他地方共享。
单例bean是应用程序范围广泛的,在所有客户端之间共享。换句话说,每个servlet将共享相同的单例EJB实例。
请注意,EJB上下文中的术语客户端和会话绝对不是与WAR语境中的那些相同,这是许多初学者堕落的地方。 EJB客户端不是webbrowser,而是EJB被注入的类的实例(在你的情况下是web servlet实例)。 EJB会话不是HTTP会话,而是EJB客户端会话。
另请参见:
I created Stateful, Stateless and singleton bean classes and trying to access them two different servlet. And running project on JBoss server.
When I access Stateful bean from each servlet two different bean object will be created and different states(data) are preserved for them. But stateless bean object is shared between both servlet. Singleton bean also behaves same way as stateless bean.
My question is why stateful and stateless bean behaves in opposite way? Is lifecycle of session bean is same as lifecycle of 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>");
}
}
Similarly, I created one more 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;
}
}
Am I missed something in code?
Everything is behaving as specified.
A stateless EJB delegates the call further to currently available instance in the pool. Apparently there's only one which is not used concurrently (yet) and therefore all clients have the same chance to access the same instance in the pool. If you fire more HTTP requests concurrently on the servlet(s), then chances increase that there's no available instance anymore and the container will create a new instance in the pool.
A stateful EJB is tied to its client (in your case, the web servlet instance). In other words, each servlet has its own stateful EJB instance which is not shared elsewhere.
A singleton bean is application wide and shared across all clients. In other words, each servlet will share the same singleton EJB instance.
Do note that the terms "client" and "session" in EJB context are absolutely not the same as those in WAR context and this is where many starters fall over. The EJB client is not the webbrowser, but the instance of the class where the EJB is injected (in your case, the web servlet instance). The EJB session is not the HTTP session, but the EJB-client session.
See also:
- @Inject stateless EJB contains data from previous request
- Why Stateless session beans?
- When using @EJB, does each managed bean get its own @EJB instance?
这篇关于为什么有状态和无状态的豆子以相反的方式行事?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!