我有一个@RequestScoped CDI bean,我想把它变成一个EJB来获取声明式事务。 (我在EJB 3.1,Java EE 6上)
目前,我在子例程之间传递状态,假设实例仅用于单个请求。如果我现在添加@Stateless
,那么假设就会改变。
例如,我想做类似
的事情@Stateless
@Named
@RequestScoped
public class Foo {
private String var1; // can't use instance vars in @Stateless?
private String var2;
public void transactionForRequest() {
var1 = value;
var2 = value;
....
subroutine();
}
}
我认为上述方法不起作用 - 这是正确的吗?
我正在考虑两种选择:
EJBContext.getContextData
map替换实例变量。哪个更好?还有其他一些我没想到的选择吗? (除了等待Java EE 7或切换到Spring。: - ))
答案 0 :(得分:12)
虽然@Stateless
,@Singleton
和@MessageDriven
可以通过@Inject
注入范围参考,但它们不能 @RequestScoped
或任何其他范围。只有@Stateful
模型足够灵活,可以支持范围。换句话说,您可以将@Stateful
bean类本身注释为@RequestScoped
,@SessionScoped
等。
简单来说,@Stateless
,@Singleton
已经修复了“范围”。 @Singleton
基本上是@ApplicationScoped
,而@Stateless
可能是@InvocationScoped
之类的组成范围,如果存在的话。 @MessageDriven
bean的生命周期完全取决于驱动它的连接器,因此也不允许具有用户定义的范围。
答案 1 :(得分:3)
我会选择SFSB而不是SLSB。你想拥有一个状态,所以对我来说这是最重要的信息 - 这是有状态EJB的工作。
此外,我认为EJBContext#getContextData()
不会对您有所帮助。据我记忆,它仅在通话期间有效。因此,每次在EJB上调用方法都会创建新的上下文数据映射(至少这是我所期望的。)
答案 2 :(得分:1)
如果您使用无状态bean,则您负责任何状态管理,并且通常使用HttpSessions在Web应用程序层中执行此操作。是的,你不能使用实例变量作为无状态bean。