【问题标题】:Lookup returns new instance of Stateful session bean查找返回有状态会话 bean 的新实例
【发布时间】:2013-11-11 10:33:13
【问题描述】:

我正在使用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>

【问题讨论】:

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


    【解决方案1】:

    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 中)并始终使用此引用来访问 EJB
    • 我想知道在这些情况下是否有一个资源可以正确(清楚地)解释这个链接到;这一定是关于有状态 bean 最被误解的事情。
    • @Korgen 是的,这可以解决问题。但它可能会对可扩展性产生负面影响。我总是尽量不使用 SFSB,或者至少在用户对话中不使用 SFSB。
    • @isnot2bad 但这正是您应该使用 SFSB 的目的......在与客户的对话期间保持状态。只要您适当地处理 bean,只要您不在“小型”服务器上为大量客户端提供服务,通常就不会遇到资源问题。如果您不想使用 SFSB,则需要通过参数将状态从客户端传递给 SLSB
    • @Korgen 我同意。也许我对这个话题有点偏执。到目前为止,大多数时候我可以使用 RESTful 方法结合富客户端(保持状态不是问题)来避免服务器端客户端状态。当然,纯网络应用程序是另一回事......
    猜你喜欢
    • 2011-08-14
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    • 1970-01-01
    • 2012-03-24
    相关资源
    最近更新 更多