【问题标题】:Difference between Stateless and Stateful session bean无状态和有状态会话 bean 之间的区别
【发布时间】:2012-01-31 09:03:04
【问题描述】:

我知道有状态 bean 在不同的实例方法调用之间保持会话会话,但无状态不会。我的问题,假设我有一个如下所示的无状态 bean 实现

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

import com.tata.ejb3.data.HelloEJBInterface;

@Stateless
public class ValueEJB implements ValueEJBInterface{

    private int value;
    @Override
    public int getValue() {
        return this.value;
    }

    @Override
    public void setValue(int value) {
        this.value = value;
    }
}

我有我的 bean 客户端(一个 servlet),它启动 bean 调用,如下所示

@EJB(mappedName="E/ValueEJB /remote")
ValueEJBInterface value;

....

value.setValue(250);
System.out.println(value.getValue());//This statement prints the value 250

....

根据我的理解,因为我的 bean 是无状态 bean,它不应该以 250 的值显示。

私有 int 值;是一个即时变量,如果一个无状态方法设置了它的值,该值将在方法退出时过期。但是在这里,即使通过我的第二个方法调用,我也能够获得值“250”。是否违反了无国籍概念?我缺什么吗?

【问题讨论】:

    标签: ejb-3.0


    【解决方案1】:

    调用不同方法时有状态和无状态 bean 行为的区别。


    STATEFUL:在有状态 Bean 上调用不同方法时,会创建不同的 bean 实例。

    ((MyStatefulBeanRemote) ctx.lookup("ejb/MyStatefulBean")).doingStatefulThing();
    
    ((MyStatefulBeanRemote) ctx.lookup("ejb/MyStatefulBean")).doingNothingStatefulThing();
    
    ***Output: Note the creation of separate objects.***
    
    INFO: Calling doingStatefulThing...com.myeclipseide.ejb3.stateful.**MyStatefulBean@2fe395**
    
    INFO: Calling doingNothingStatefulThing...com.myeclipseide.ejb3.stateful.**MyStatefulBean@81cfcb**
    

    STATELESS:当在无状态 Bean 上调用不同的方法时,这些 bean 会被池化,因此不会创建 bean 的新实例。

    ((MyStatelessBeanRemote) ctx.lookup("ejb/MyStatelessBean")).doSomething(); 
    
    ((MyStatelessBeanRemote) ctx.lookup("ejb/MyStatelessBean")).doNothing();
    
    ***Output: Note the reuse of he bean object.***
    
    INFO: Doing something ...com.myeclipseide.ejb3.stateless.**MyBean@213b61**
    
    INFO: Doing Nothing ...com.myeclipseide.ejb3.stateless.**MyBean@213b61**
    

    【讨论】:

      【解决方案2】:

      有趣的问题,基本上你是完全正确的。我做了一些研究,一般的建议是:“期望你的 bean 在每次方法调用之后忘记一切......”(page 81)。此外,根据该资源,负责维护无状态会话 Bean 状态的算法是特定于容器/供应商的。所以容器可以在方法执行后选择销毁、重新创建或清除实例。

      您可以创建一个多线程测试,并查看它在多个客户端上的表现。

      【讨论】:

      • 好吧。你是对的。如果我没记错的话,类似的场景在 EJB2.0/Weblogic ejb 容器中表现不同,我的 EJB 客户端将 0 作为 getValue,这意味着在我的下一次调用中,容器使用不同的 ejb 实例提供服务。
      【解决方案3】:

      没有违反任何概念。这是因为容器从池中选择了相同的 bean 实例来服务其他请求。

      无状态 bean 是池化的,因此它们比有状态 bean 具有性能优势,而且它们的主要目的是在不保持任何状态的情况下进行处理。

      不应将敏感数据或用户特定数据存储在无状态 bean 的实例变量中。它们应该被广泛用于处理数据而不考虑状态。

      可以参考here 获取容器处理的生命周期事件。

      【讨论】:

      • 感谢您提供详细信息。这里还有一个问题。 @stateless(mappedName="XXX"),我的 ejb 之后会在这里通过 XXX 引用吗?尽管有 XXX,但我已经看到 JBoss AS 给出了不同的 JNDI 映射。它纯粹是特定于供应商的吗?
      • 不,mappedName 是可选属性,由供应商决定,JBoss 选择退出此属性并使用自己的约定。
      • 我注意到一件更有趣的事情,mappedName 仅在我的服务接口是 Remote 接口时才使用。当我为 EJB 指定 mappedName 时,它​​的服务接口使用 @Local 注释(或者这里甚至没有指定任何内容) ,我的 JBoss 容器忽略了它并绑定了自己的 JNDI,类似于 xxxxx/Local
      • 可以使用JBoss特定的注解@LocalBinding@RemoteBinding
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-26
      • 1970-01-01
      • 2013-02-04
      • 1970-01-01
      • 1970-01-01
      • 2012-10-30
      相关资源
      最近更新 更多