Java 查找返回有状态会话bean的新实例

Java 查找返回有状态会话bean的新实例,java,jakarta-ee,ejb-3.0,stateful-session-bean,Java,Jakarta Ee,Ejb 3.0,Stateful Session Bean,我正在使用JavaEE5,EJB3.0,JBossAS4.3.2 我有最简单的Statefulbean @Local public interface IStateBean { } @Stateful public class StateBean implements IStateBean { private static int number = 0; @PostConstruct void init() { number++; Syst

我正在使用
JavaEE5
EJB3.0
JBossAS4.3.2

我有最简单的
Stateful
bean

@Local
public interface IStateBean 
{
}
@Stateful
public class StateBean implements IStateBean
{  
   private static int number = 0;

   @PostConstruct
   void init()
   {
      number++;
      System.out.println("@PostConstruct: " + number);
   }

   @PreDestroy
   void destroy()
   {
      number--;
      System.out.println("@PreDestroy: " + number);  
   }
}
我在servlet中查找这个bean

public class MyServlet extends HttpServlet
{  
   @Override
   public void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException
   {  
      IStateBean bean = new InitialContext().lookup("app-ear/StateBean/local");
      // ...
   }
}  
但是每次创建
StateBean
的新实例时。
我可以调用
lookup
两次,但会再次创建
StateBean
的新实例

   @Override
   public void doGet(final HttpServletRequest aRequest, final HttpServletResponse aResponse) throws ServletException, IOException
   {  
      IStateBean bean1 = new InitialContext().lookup("app-ear/StateBean/local"); 
      IStateBean bean2 = new InitialContext().lookup("app-ear/StateBean/local"); // new instance is created
      // ...
   }  
我希望同一http会话中有相同的实例

web.xml中的Servlet映射

   <servlet>
      <servlet-name>MyServlet</servlet-name>
      <servlet-class>com.package.MyServlet</servlet-class>
   </servlet>  
   <servlet-mapping>
      <servlet-name>MyServlet</servlet-name>
      <url-pattern>*.html</url-pattern>
   </servlet-mapping>

MyServlet
com.package.MyServlet
MyServlet
*.html

EJB规范没有说,多次查找将返回有状态会话bean的同一实例。相反:服务器甚至需要创建两个不同的实例,以保证每个客户机在服务器上都有自己的实例

EJB规范只说明,当您引用有状态会话bean时,它会在多个方法调用中保留其内部状态:

IStateBean bean = new InitialContext().lookup("app-ear/StateBean/local");
bean.myMethod1();
bean.myMethod2(); // affects the same EJB instance on the server

请注意,在使用无状态会话bean时,情况可能并非如此。在这里,上面显示的两个方法调用可能会转到服务器上的不同实例

我同意。。。为了解决这个问题,您应该将对statefull bean的引用存储在客户端(例如,在调用者的HTTPSession中),并始终使用该引用访问EJBI,不知道在这些情况下是否有一个资源可以正确(清楚地)解释链接到它;这肯定是有状态bean有史以来最容易被误解的地方。@Korgen是的,这将解决问题。但它可能会对可伸缩性产生负面影响。我总是尽量不使用SFSB,或者至少不在用户对话中使用SFSB。@isnot2bad,但这正是您应该使用SFSB的原因。。。在与客户端对话期间保持状态。只要您适当地处理bean,通常不会遇到资源问题,只要您不在“小型”服务器上为大量客户机提供服务。如果不想使用SFSB,则需要通过将状态从客户端传递给SLSBparameters@Korgen我同意。也许我对这个话题有点偏执。到目前为止,大多数情况下,我可以使用RESTful方法结合富客户机避免服务器端客户机状态(在富客户机中,保持状态不是问题)。当然,纯网络应用是另一回事。。。