我有一个@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();
}
}
我认为上述方法不起作用-正确吗?
我正在考虑两种选择:
与@Named和@RequestScoped一起使用@Stateful而不是@Stateless。
保持@Stateless并使用
EJBContext.getContextData
映射替换实例变量。哪个更好?还有我没有想到的其他选择吗? (除了等待Java EE 7或切换到Spring。:-)
最佳答案
尽管@Stateless
,@Singleton
和@MessageDriven
可以通过@Inject
注入作用域引用,但它们不能是@RequestScoped
或任何其他作用域。仅@Stateful
模型具有足够的灵活性以支持范围。换句话说,您可以将@Stateful
bean类本身注释为@RequestScoped
,@SessionScoped
等。
简单来说,@Stateless
,@Singleton
已经具有固定的“作用域”。 @Singleton
本质上是@ApplicationScoped
,如果存在的话,@Stateless
可能是像@InvocationScoped
这样的组合范围。 @MessageDriven
bean的生命周期完全取决于驱动它的连接器,因此也不允许具有用户定义的范围。
另见https://stackoverflow.com/a/8720148/190816