我有一个@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

09-10 14:57