其实他的生命周期试这个session bean的生命期,而不是整个的application,如果再一段时间后,容器消除了这个session bean的实例,那么这个之也就不再了,当再一次一个jsp需要这个bean,容器创建她,他右存在了,在这个过程中,无论哪一个client调用这个bean,其实都是使用唯一的一个。所以他们的值试相同的。

解决方案 »

  1.   

    这样你就得出结论了我的一个无状态bean就可以满足所有的你的请求   
    根本不用回收就可以重新利用  要是访问多的话估计结果会不一样没经过试验  求证
      

  2.   

    其实他的生命周期试这个session bean的生命期,而不是整个的application
    ---------------------------------------------------------------------
    对,这样描述更准确。
    我的一个无状态bean就可以满足所有的你的请求   
    根本不用回收就可以重新利用  要是访问多的话估计结果会不一样
    -----------------------------------------
    请详细解释一下,没看懂
      

  3.   

    呵呵,你渐渐明白一点了.但你考虑过生成两个bean的情况没?那样你的"记数器"就完全垮掉了 :(
    无状态的意思就是没有成员变量... ------------------------------------------------------
               我们还年轻牛奶会有的奶牛也会有的 
                 可天天在 csdn 混这些会有吗 ??
      

  4.   

    但你考虑过生成两个bean的情况没?那样你的"记数器"就完全垮掉了
    -------------------------------------------------------------------
    无状态BEAN的特征是,面对任何一个客户请求,EJB容器都可以任意选择一个无状态BEAN实例来处理,因为这些实例是相同,也许它们的数量不至一个,但是它们的所有成员变量都是同步的,否则的话,这两个实例又怎么能说是相同的呢.
    你有做过测试吗,它生成过两个实例,但是他们的成员变量不同吗?
      

  5.   

    无状态的意思就是没有成员变量...你的有变量的sessinbean本身就不是一个无状态sessionbean了...
    "因为这些实例是相同" 是说没有自己变量的sessionbean,只有方法,所以是相同的...
    它们的成员变量不会同步,而是取各自的值 ...
    你又做过测试吗?我没测试,我是凭我的理解.
    你没测试,你是凭书上的只言片语
    :)
    要不你测一下? ------------------------------------------------------
               我们还年轻牛奶会有的奶牛也会有的 
                 可天天在 csdn 混这些会有吗 ??
      

  6.   

    你的有变量的sessinbean本身就不是一个无状态sessionbean了...
    ---------------------------------------------------------------
    它还是!千万不要认为有态SESSION BEAN和它的差别就是是否设置了成员变量,它们的差别是在部署描述符里对SESSION类型的指定。
    下面是一个详细的测试例子,你可以拿去跑起来看看:REMOTE接口
    ------------------------------------------------------------------
    package myStatefulEJB; import java.rmi.*;
    import javax.ejb.*;public interface Simple extends EJBObject {
       public int getNumber() throws RemoteException;}HOME接口
    ---------------------------------------------------------------------
    package myStatefulEJB; import java.rmi.*;
    import javax.ejb.*;public interface SimpleHome extends EJBHome 
    {
      public Simple create() throws RemoteException, CreateException;  
    }BEAN类
    --------------------------------------------------------------------------
    package myStatefulEJB; import java.rmi.*;
    import javax.ejb.*;public class SimpleBean implements SessionBean {
      private SessionContext context;
      private int number=0;//定义成员变量
      public int getNumber() throws RemoteException {
      return ++number;
      }  /**
       * Callback method.
       */
      
      public void ejbCreate() throws RemoteException, CreateException
      {
      }
      
      
      /**
       * Callback method.
       */
      public void ejbRemove() throws RemoteException 
      {  
       System.out.println("ejbRemove()");
      }  /**
       * Callback method.
       */
      public void ejbActivate() throws RemoteException 
      {  
       System.out.println("ejbActivate()");
      }  /**
       * Callback method.
       */
      public void ejbPassivate() throws RemoteException 
      {  
       System.out.println("ejbPassivate()");
      }  /**
       * Save the SessionContext.
       */
      public void setSessionContext(SessionContext context)  throws RemoteException {
        this.context = context;
      }  public SessionContext getSessionContext() throws RemoteException {
            return (SessionContext) context;
      }
    }
    ejb-jar.xml
    ----------------------------------------------------------------------------------------------
    <?xml version="1.0"?>
    <!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/j2ee/dtds/ejb-jar_2_0.dtd"><ejb-jar>
    <enterprise-beans>
     <session>
      <display-name>Simple</display-name>
      <ejb-name>Simple</ejb-name>
      <home>myStatefulEJB.SimpleHome</home>
      <remote>myStatefulEJB.Simple</remote>
      <ejb-class>myStatefulEJB.SimpleBean</ejb-class>
      <session-type>Stateless</session-type>
      <transaction-type>Container</transaction-type>
      </session>
    </enterprise-beans>
    <assembly-descriptor>
    </assembly-descriptor>
    </ejb-jar>
    jsp client
    ------------------------------------------------------------------------------------------------
    <%@ page import="myStatefulEJB.*,java.rmi.*,javax.rmi.*"%>
    <%
    try 
            { javax.naming.InitialContext ctx = new javax.naming.InitialContext();    
            Object o = ctx.lookup("Simple");
            SimpleHome home = (SimpleHome)PortableRemoteObject.narrow(o, SimpleHome.class);
           Simple test1 = home.create();
           Simple test2 = home.create();

    out.print("<p>test1:"+test1.getNumber());
    out.print("<p>test2:"+test2.getNumber());
        
         if(test1.isIdentical(test2))
          out.print("<p>test1 is identical test2!");
         else
          out.print("<p>test1 is NOT identical test2!");
        
        
            } catch (Exception e) {
               System.out.println(e.toString());
            } 
    %>上面生成了两个EJB对象test1,test2,你发现它们的成员变量都指向同一个值,当test1.getNumber()增加了Number的值后,test2获取到的是这个已经改变了的值。
    通过判断实例是否相同test1.isIdentical(test2),会打印它们是相同的实例。
      

  7.   

    无状态的意思就是没有成员变量... 我的意思是说如果你的bean需要变量了,那就要设成有状态的,否则这个变量根本就是无意义的,因为它的取值不是你所能控制的.一般情况下容器里当然只有一个无状态实例在运行,所以你对它的变量的操作其他程序肯定会发现也变化了... 但这只是因为整个容器里只有这一个实例..
     我的意思是如果有两个实例同时运行呢? 你这个程序发现里面的i(假设是一个变量) 是8.另一个引用这个实例的值肯定也是8,这里加一,那另一个肯定也就成了9了..但还有另一个程序引用的是容器里另一个无状态sessionbean呢? 它的值就有可能是 1,是2,是4..总之,是和前一个sessionbean里的值没有任何关系...你的例子里运行的还是同一个实例,所以看不出有什么混乱来...至于什么时候容器会生成两个或以上的无状态sessionbean.那就是容器的事了... ------------------------------------------------------
               我们还年轻牛奶会有的奶牛也会有的 
                 可天天在 csdn 混这些会有吗 ??
      

  8.   

    无状态的意思就是没有成员变量... 我的意思是说如果你的bean需要变量了,那就要设成有状态的,否则这个变量根本就是无意义的,因为它的取值不是你所能控制的.一般情况下容器里当然只有一个无状态实例在运行,所以你对它的变量的操作其他程序肯定会发现也变化了... 但这只是因为整个容器里只有这一个实例..
     我的意思是如果有两个实例同时运行呢? 你这个程序发现里面的i(假设是一个变量) 是8.另一个引用这个实例的值肯定也是8,这里加一,那另一个肯定也就成了9了..但还有另一个程序引用的是容器里另一个无状态sessionbean呢? 它的值就有可能是 1,是2,是4..总之,是和前一个sessionbean里的值没有任何关系...你的例子里运行的还是同一个实例,所以看不出有什么混乱来...至于什么时候容器会生成两个或以上的无状态sessionbean.那就是容器的事了... ------------------------------------------------------
               我们还年轻牛奶会有的奶牛也会有的 
                 可天天在 csdn 混这些会有吗 ??
      

  9.   

    如果你都请求的不是这个无态SESSION BEAN,而是另外一个不同的SESSION BEAN,那肯定实例不相同了,但肯定不会串的,经常在一个文件里面请求多个不同的SESSION BEAN,不可能发生请求第一个无态BEAN的方法,它调用到另外一个无态BEAN方法去了,怎么可能呢。
    这里要区别开一个无态BEAN的所有实例是相同的;但是如果这个无态BEAN都不同,那它的实例肯定就不相同了。
      

  10.   

    无状态session bean并不维持任何对话状态。每个方法是完全独立的,而且只使用传递来的参数数据;从所有bean类型的产量和资源消耗方面来说,无状态session bean提供了最高效率,因为少数无状态session bean实例需要服务于成百、上千的客户端。
       无状态session bean的实例交换:(stateless session bean)
     例如:实例A正在为由EJB对象1传递的商务方法调用服务。一旦实例A完成为请求服务后,它就返回实例池中,等收到EJB对象上的一个商务方法调用时,实例A就与这个EJB对象在操作期间相联系。当实例A为EJB对象2服务时,EJB对象1从客户端收到另一个方法调用,就由实例B来为其服务。使用这种策略能使一些无状态session bean的实例为上百个客户端服务;
    一旦一个作为无状态被配置后,容器就假定在方法调用中不为它维持任何对话状态。所以虽然一个无状态bean能有实例变量,但由于bean的实例可能为不同的EJB对象服务,它们不应该维持对话状态。
      

  11.   

    如果你都请求的不是这个无态SESSION BEAN,而是另外一个不同的SESSION BEAN,那肯定实例不相同了,但肯定不会串的,经常在一个文件里面请求多个不同的SESSION BEAN,不可能发生请求第一个无态BEAN的方法,它调用到另外一个无态BEAN方法去了,怎么可能呢。你理解错了,也可能是我说的不清楚这里说的sessionbean 当然就是同一个sessionbean
    但你应该知道sessionbean在容器里是放在池里的,一个sessionbean,不同的应用调用它,容器就直接返回池里的这个bean的一个实例.. 如果池里只有一个bean.那么你所有的应用调用sessionbean的时候,调用的都是这一个bean,当然里面的参数值都是一样的.. 我的意思是说这个池里如果有两个bean的实例.是同一个bean的两个实例,而不是两个不同的bean .那这是候这个bean的两个实例里的各自的变量就肯定是没有关系的了.... ------------------------------------------------------
               我们还年轻牛奶会有的奶牛也会有的 
                 可天天在 csdn 混这些会有吗 ??
      

  12.   

    同意 zez(思恩 为老婆多挣钱 鹤清风) 如果你的bean需要变量了,那就要设成有状态的,否则这个变量根本就是无意义的,因为它的取值不是你所能控制的,至于什么时候容器会生成两个或以上的无状态sessionbean.那就是容器的事了这段代码:
    Simple test1 = home.create();
    Simple test2 = home.create();
    碰巧容器用同一个Bean实例返回,所以看起来像是有状态的但你不能依赖于容器的行为(程序员无法控制)。
      

  13.   

    我的意思是说这个池里如果有两个bean的实例.是同一个bean的两个实例,而不是两个不同的bean .
    --------------------------------------------------------------------------
    通常EJB容器都有BEAN实例池,可以配置这个实例池BEAN实例的数量,而且这个数量默认值多半不是1(你可以任意改变它),也就是说跑上面例子的时候,容器里实例数量是不至一个的,但是这些个实例呢都又是相同的,这种相同包括它们各自的成员变量也在同步相同,也就是说任何一个时刻,某一个实例中的成员变量是多少,那其他实例的成员变量也是多少,它并没有维持什么状态,它只是保持了实例的完全同一性,保证了无态会话BEAN的特征,用任何一个实例都可以拿来做相同的服务。
    当然,在无态会话BEAN里定义成员变量首先就是不对的,但是这个测试有助于深刻理解无态会话BEAN在容器里的运行机制。
      

  14.   

    对无状态的sessionbean的一个方法调用后,如果服务器的客户特别多,池化的实例不足以满足需要,那么为这个方法服务的实例就转向为其他客户服务,他不会保存任何原来方法调用的结果信息,不像有状态的sessionbean会调用ejbpassive()。所以同一个客户的下一个远程调用就可能是另外一个实例为他服务了,前一个的变量结果不会保存下来。
      

  15.   

    容器里实例数量是不至一个的,但是这些个实例呢都又是相同的
    -------------
    这个理解是错误的,实际上容器里面存在多个bean的实例,它们没有任何的同步关系
    你通过程序测试发现好像都是同步仅仅是因为你的测试程序是顺序执行而并没有并发只要你的测试代码存在并发的情况,那么你就会发现容器实际上存在的各个bean实例并
    不存在同步关系
      

  16.   

    你可以不断刷新浏览器,甚至开几个窗口同时进行
    ------------------------------------------------
    通过这样的动作,应该不存在顺序执行吧,并发也可能产生吧。你用过数据库连接就应该知道,不停的刷新浏览器是最容易产生并发请求的。
    容器里实例数量是不至一个的,但是这些个实例呢都又是相同的
    --------------------------------------------------------
    实例数量是不至一个应该没有错吧
    实例呢都又是相同的难道有错?如果实例都不同,它怎么实现少数无状态session bean实例需要服务于成百、上千的客户端。
    我觉的现在问题争论的焦点就是在“如果实例包含了成员变量,它们就是不同的;如果没有包含,它们就是相同的”和“容器里是只有一个实例还是有多个,如果只有一个,那么上面的例子只是偶然的,但是有多个的话,它难道每次都碰巧找到上次那个吗”
      

  17.   

    这段代码:
    Simple test1 = home.create();
    Simple test2 = home.create();
    碰巧容器用同一个Bean实例返回,所以看起来像是有状态的
    -------------------------------------------------------
    我们调用create()方法的时候,容器并不一定需要创建EJB实例,这一条要知道。就像我们使用连接池一样。实际上,容器只需返回一个远程接口的实例。关于无状态会话Bean的实例池:
    在EJB容器中,Weblogic Server使用一种称为实例池的技术,集中管理无状态会话BEAN实例。EJB服务器可以按照EJB规范定义,每调用一次业务方法,就创建一个新的实例,但这种做法效果不好。另一种选择是,容器只建一个实例,令所有方法调用都使用这个实例。这种做法除非方法调用很短,否则性能会受极大的影响。
    因此,WLS使用实例池,当有方法调用时,EJB容器就从实例池中取一个实例,方法调用完成后,再送回实例池,每个Bean类实例基本上是等同的。这里说的是基本上相同。
    事实上,并不是说你的bean有变量了,那就要设成有状态的,否则这个变量根本就是无意义的。这种说法也不正确。例如:有这样一个例子,是一个AccountEJB,两个方法。一个查帐户余额,一个存款。这样就需要用到数据库连接,那么你认为数据库连接是作为一个属性好,还是在每个方法里去创建好呢?如果这个EJB有十个需要数据库连接的方法呢?很显然,作为属性是正确的,而且重要的是对每个实例来说,也许每个数据库连接的内存地址并不一样,但这并不影响我们的结果。在这种情况下,无状态会话Bean中的属性是有意义的,而且这样做是很好的。
      

  18.   

    windowsjava(小人物):
    你这一大段话只是说明了,无状态会话Bean中的属性是有意义的,它可以保存一些不经常改变的变量,这样做很好。但是你回避了这里的关键问题:如果这个变量被改变了,那么其他实例的这个变量会不会跟着改变?
    上面的例子测试是也跟着变了,所以很奇怪,我就说这个变量保持了同步,但是他们反驳说只是一种偶然现象,是因为每次都找的是上次使用的那个实例所以才那样。但是容器从实例池里随便找一个实例服务,难道每次都找到上次那个吗?
      

  19.   

    其实就是一个选择题:有一个无态bean,定义了一个实例变量,并且它在连结池中有多个实例,同时被不同的程序引用着。
    A.这个变量在不同的实例中始终保持同步
    B.这个变量在不同的实例中有着各自不同的值楼主好像选A,还有一些选B.到底选什么,我也想知道!
      

  20.   

    我觉得不是同步的。我也试了一下。我在create()方法中加了一句Thread.sleep(10000),并加了一句System.out.println("ejbCreate");然后选定weblogic,以使它不运行,现在在开三个IE窗口。当我取消了选定weblogic时,三个页面运行后的值是这样的:第一个是1,2,第二个是1,2,第三个是3,4。我没有开第四个页面,我想如果开了的话,第四个有可能是3,4,也有可能是5,6.
    我的意思是:这些实例中的变量不是同步的。除非你碰到了相同的那一个。
      

  21.   

    同意  windowsjava(小人物) ,这些变量并不同步
    “但是容器从实例池里随便找一个实例服务,难道每次都找到上次那个吗?”
    注意,“随便找一个实例服务”这样说是不正确的,对于不同的AS可能做法不一样,譬如我可以这样做:尽可能使用第一个可用的Bean,而不是轮流使用就是这个实例池是一个栈,总是找到最上面一个可用的Bean,当用完以后又重新压栈回到最上层。所以当顺序执行的时候,总是找到同一个当然上述这样算法并不是硬性规定,可能不用Server之间做法不一样
      

  22.   

    question:
    1 stateless bean pool是否永远不会调用ejbRemove?
    2 stateless bean pool是否永远不会调用ejbActivate,ejbPassivate? statefule bean肯定是要调用的。
    3 EJB容器(特别是轻量级的容器)有没有这样的实现,对stateless bean,只产生一个实例,并发访问时排队等候(此时各个客户端实际访问同一个Bean)?
      

  23.   

    “但是容器从实例池里随便找一个实例服务,难道每次都找到上次那个吗?”
    注意,“随便找一个实例服务”这样说是不正确的,对于不同的AS可能做法不一样,譬如我可以这样做:尽可能使用第一个可用的Bean,而不是轮流使用
    ------------------------------------------------------------------
    可能你的观点是正确的,有点涉及到各自不同EJB容器的算法实现了,我这里用的是JRUN,没有用WLG试过,windowsjava(小人物)在WLG上测试,如果出现了“第一个是1,2,第二个是1,2,第三个是3,4。”这样的情况,那也就是说各个实例的成员变量是不一样的,而我在JRUN上的测试只是因为JRUN“尽可能使用第一个可用的Bean”所以才产生了那种同步的情况。谢谢大家热情参与。
      

  24.   

    question:
    1 stateless bean pool是否永远不会调用ejbRemove?
    -----------------------------------------------------
    会调用2 stateless bean pool是否永远不会调用ejbActivate,ejbPassivate? statefule bean肯定是要调用的。
    ------------------------------------------------------
    不会调用3 EJB容器(特别是轻量级的容器)有没有这样的实现,对stateless bean,只产生一个实例,并发访问时排队等候(此时各个客户端实际访问同一个Bean)?
    -------------------------------------------------------
    如果这样实现效率太低,应该都是维持一定数量的实例
      

  25.   

    关于EJB容器里的实例谁也不能把它打印出来看看,只能对着黑箱揣测它里面到底在发生些什么,所以这个问题再讨论下去就僵化了。
      

  26.   

    “但是容器从实例池里随便找一个实例服务,难道每次都找到上次那个吗?”
    注意,“随便找一个实例服务”这样说是不正确的,对于不同的AS可能做法不一样,譬如我可以这样做:尽可能使用第一个可用的Bean,而不是轮流使用
    ------------------------------------------------------------------
    实例池的设计一般有两种方式:先进先出(FIFO),先进后出(FILO).
    前面大家讨论的多个实例之间是否同步,我个人认为是不同步的(当然也测试过),但是对于,container中只有业务处理不多时(也就是说,任何时刻只有一个instance就可以为所有的请求服务,或者说所有的请求是一个接一个来的,并且实例池的设计采用先进后出(FILO)设计方式),那么我们就可能每次都用到同一个instance,所以得出的结果感觉上是同步的(其实是巧合)。
       对于stateless session bean,是处理通用业务,比如发送email的bean,如果要用到上次的状态就的考虑用stateful session bean了。-------------------------------------------------------------------------------
        为了生活,女的也可以搞IT,并且也可以搞好。
      

  27.   

    我还有一个关于有态SESSION BEAN的问题,题目是:“使用有态SESSION BEAN和在SESSION里面放一个JAVA BEAN有什么区别?”,地址是:http://expert.csdn.net/Expert/topic/2259/2259157.xml?temp=.9277002欢迎大家前去讨论。