Lookup返回有状态会话bean的新实例

时间:2013-11-11 10:33:13

标签: java java-ee ejb-3.0 stateful-session-bean

我正在使用Java EE 5EJB 3.0Jboss AS 4.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-session中的相同实例

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>

1 个答案:

答案 0 :(得分:9)

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时可能不是这种情况。在这里,上面显示的两个方法调用可能会转到服务器上的不同实例!