我想我在这里有一个基本的理解问题,我希望有人能给我解释一下。
假设我们有一个有状态EJB_A、一个有状态EJB_B和一个会话作用域ManagedbeanA:
@Stateful
@LocalBean
public class EJB_A {
}
@Stateful
@LocalBean
public class EJB_B {
@EJB
EJB_A ejb;
}
@ManagedBean
@SessionScoped
public class ManagedBeanA {
@EJB
EJB_A ejb;
}在ManagedBeanA中,将创建EJB_A。现在,当我使用EJB_B时,会在EJB_B中创建一个新的EJB_A实例,它与之前在ManagedBeanA中创建的EJB_A实例不同。
我不理解这一点,因为我认为有状态EJB的全部意义在于,对于每个客户端,EJB-Container只创建、共享和管理一个实例。有人能给我解释一下吗?另外,请解释一下如何实现EJB的同一实例被多个其他EJB共享?
谢谢
发布于 2012-11-30 17:34:42
是的,你混淆了不同的概念,还有不同的APIS……我宁愿使用@Inject而不是@EJB,并指定注入实例的作用域。
@Stateful
@LocalBean
public class EJB_A {
}
@Stateful
@LocalBean
public class EJB_B {
@Inject @SessionScoped
EJB_A ejb;
}
@ManagedBean
@SessionScoped
public class ManagedBeanA {
@Inject @SessionScoped
EJB_A ejb;
}发布于 2012-11-30 17:26:55
我刚刚读了一些here。
这是因为每次查找EJB3.0有状态会话bean远程或本地业务接口的
()都会导致创建一个新的bean标识。查找返回的每个引用都引用一个不同的有状态会话bean。它由调用者决定如何管理对该引用的访问。通常,web应用程序会将引用存储在HttpSession或应用程序范围(ServletContext)范围内,以供后续访问。
和:
在您的例子中,不要忘记我们正在处理两种类型的会话:
会话和web会话。前者确保一旦您请求有状态bean,它的标识在整个用户会话中保持不变。但是当您使用后者时,您在bean会话之上有一个web会话。为了确保从两个不同的JSP访问相同的bean (或者在重新加载时),您需要将bean的标识存储到web会话作用域中。
所以你实际上是对的。当您想要使用您的实例时,您必须使用ManagedBean在其他地方检索它,因为EJB实例与这个会话上下文相关联。因此,如果您想简化它,并确保每个会话只存在一次EJB,那么可以使用CDI并使用@javax.enterprise.context.SessionScoped对EJB本身进行额外的注释。
发布于 2012-11-30 16:44:05
我想我混淆了两个东西-- @Sessionscoped和@Stateful。
@Stateful注释并不意味着每个客户端只创建一个实例。这只意味着@Stateful-EJB只属于一个客户端,而@Stateless-EJB可以由多个客户端共享。
因此,@Stateful-EJB具有N:1关系(N @Stateful-EJB恰好属于一个客户端),而@Stateless-EJB具有N:M关系(N @Stateless-EJB属于M个客户端)。这意味着一个EJB实例不能被多个其他EJB共享,只使用@有状态EJB的@EJB-Annotation。
另一方面,@Sessionscoped Managedbean似乎每个客户端只创建一次。
我说对了吗?
https://stackoverflow.com/questions/13634318
复制相似问题