EJB是如何维持有状态会话bean状态的?

在servlet中使用有状态会话bean,得通过jndi查找的方式,如果有状态会话bean还跨请求,只被一个用户客户端共享(不被多个用户客户端所共享),那还要把ejb放到httpsession中去。例如:InitialContext ctx = new InitialContext(); statefulEJB = (StatefulEJB)ctx.lookup("java:comp/env/StatefulEJB"); httpSession.setAttribute("statefulEJB", statefulEJB);这样同一个用户客户端的多次请求就可以共享一个statefulEJB了,状态得到了保存。我主要是想问下,web应用情况下,ejb容器取得bean是会从httpsession中寻找吗(找得到就用)?如果会,那容器怎麽知道httpsession的存在(如果是桌面应用就没httpsession)?如果不是从httpsession中找的,那容器是如何保证取得的有状态会话bean就是同一个用户客户端的那个,而不是其他用户客户端的bean呢?谢谢banq大哥或其他大侠帮忙解惑。

同一个lookup就是同一个sfsb

>>ejb容器取得bean是会从httpsession中寻找吗(找得到就用)?如果会,那容器怎麽知道httpsession的存在(如果是桌面应用就没httpsession)?

首先要知道,EJB是RMI的,因此你JNDI lookup后仅仅是个stub,你的httpsession里hold住的也仅仅是stub,至于你说的状态,用SFSB的话,状态就与httpsession没关系了,状态保存到ejb容器里,而web容器里只是一个stub.

stub(客户端-桌面应用程序,web组件)--> skeleton --> ejb object --> ejb bean

非常感谢解惑。
我想再问下,如果有状态会话bean存到httpsession里面去了,但是该有状态会话bean被销毁了(可能是很久没用,超时了被销毁了(钝化很久了),也有可能是调用了@Remove注解的方法销毁的),此时存在httpsession里面那个变量还在吗?如果还在(不是null),那从httpsession里面取出来,再调用Remote方法,会有什麽效果?(有状态会话bean里面指的session和httpsession应该完全不是一个东西。)

钝化 锐化
看看 《精通EJB》就知道了

httpsession中的是stub,这个stub除非你显示清楚,否则不会被置为null,如果SFSB超时,你再调用的话,将得到一个好像是:指定ID的bean不存在异常。

httpsession中的是stub,这个stub除非你显示清楚,否则不会被置为null
-->谢谢xmuzyu,这个我明白了。那如果有状态会话bean先被存入httpsession,然后被销毁,之后,又通过statefulEJB = (StatefulEJB)ctx.lookup("java:comp/env/StatefulEJB")类似语句lookup出一个,这时,lookup出的statefulEJB应该和httpsession里面保存的那个没有一点关系吧?重新lookup出来的应该是个新的。如果调用从httpsession里面取出来的bean的remote方法一样会报异常,我这样想对吗?

如果SFSB超时,你再调用的话,将得到一个好像是:指定ID的bean不存在异常。
-->NoSuchEJBException