3

EJB3 会话 bean 是否有请求范围的上下文?我的环境是 Java-EE-5。

这个例子

@Remote(SessionFacade.class) @Stateless
public class SessionFacadeBean implements SessionFacade {
  @EJB
  private Other bean;

  public void myBusinessMethod() {
     // TODO: get or create *myRequestScope*
     *myRequestScope*.put("demo", Integer.valueOf( 1 ));
     bean.otherBusinessMethod();
     sysout(*myRequestScope*.get("demo"));
  }
}

@Local(Other.class) @Stateless
public class OtherBean implements Other {
  public void otherBusinessMethod() {
     // TODO: get or create *myRequestScope*
     *myRequestScope*.put("demo", Integer.valueOf( 2 ));
  }
}

调用 SessionFacadeBean#myBusinessMethod() 时应始终打印输出“2” - 无论并行调用如何。

我没有使用 CDI 的奢侈。而且,它还应该独立于事务传播(因此 JCA 也不是一个选项)。

4

2 回答 2

1

无状态 EJB,顾名思义就是不存储状态,因此没有请求范围的概念。有一个会话范围仅限于当前运行时会话上下文,您也不能在其中存储状态,因此排除了在 bean 或容器中存储状态的任何选项。

您可能会通过使用变量找到一些运气ThreadLocal,但顾名思义,这仅限于当前执行线程。根据您发布的代码,这似乎是您想要的。这种方法的问题在于,

  • Thread一旦 EJB 方法完成执行,对象就不会被销毁;它们被返回到容器的线程池。因此,如果您在不同的执行上下文中读取 ThreadLocal 值,您将找到使用相同线程的先前执行上下文的值。换句话说,确保您的应用程序在读取它们之前始终将值放入 ThreadLocal 对象中。
  • 此外,一旦你不需要它们,释放任何 ThreadLocal 对象,否则你会遇到内存泄漏。
于 2011-06-05T10:08:55.477 回答
0

无状态会话 bean 是否有请求范围的上下文?

简短的回答是不。

长答案是:您需要一些上下文来在业务方法的调用之间共享数据。这可能是一个设计问题。Requestscope 是 Web 层的概念。

  • 在 Web 层中,请求、页面、会话和应用程序范围被实现为 Hashmap。因此,您可以传递对 Hashmap 的引用作为上下文来共享所有数据。

  • 另一种方法是使用单例(需要在节点之间共享,例如使用 ehcache)。

  • 迁移到 EJB 3.1 并使用 @Singleton

  • 考虑使用有状态 Bean 并将您的请求范围放入 bean 会话范围中,在您离开请求范围后可以将其删除。

于 2011-06-05T10:08:26.757 回答