请求无状态会话Bean的作用域上下文

时间:2011-06-05 09:21:30

标签: java ejb-3.0 java-ee-5

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也不是一种选择)。

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

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

简短回答是否。

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

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

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

  • 迁移到EJB 3.1并使用@Singleton

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