JavaEE6在有状态EJB之间共享实例
我想我有一个基本的理解问题,我希望有人能给我解释一下 假设我们有一个有状态EJB_a和一个有状态EJB_B以及一个会话范围的ManagedbeanA:JavaEE6在有状态EJB之间共享实例,java,java-ee-6,ejb-3.1,Java,Java Ee 6,Ejb 3.1,我想我有一个基本的理解问题,我希望有人能给我解释一下 假设我们有一个有状态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
@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_A作为属性,在EJB_B中创建了一个新的EJB_A实例。它与之前在ManagedBeanA中创建的EJB_A实例不同
我不理解这一点,因为我认为有状态EJB的全部要点是,对于每个客户机,EJB容器只创建、共享和管理一个实例。有人能给我解释一下吗?还请解释我如何实现同一个EJB实例被多个其他EJB共享
谢谢我想我把两件事搞混了-@Sessionscoped和@Stateful @Stateful注释并不意味着每个客户端只创建一个实例。这只意味着@Stateful EJB只属于一个客户机,而@Stateless EJB可以由多个客户机共享 因此@statefulejb有一个N:1关系(N@statefulejb只属于一个客户机),而@Stateless EJB有一个N:M关系(N@Stateless EJB属于M个客户机)。这意味着一个EJB实例不能通过仅使用@EJB注释来共享@Stateful EJB,而被多个其他EJB共享 另一方面,@Sessionscoped Managedbean似乎只为每个客户端创建一次 我说对了吗 我只是读了一些书 原因是EJB3.0有状态会话bean的每个lookup() 远程或本地业务接口导致创建新的 bean身份。从查找返回的每个引用都引用一个 不同的有状态会话bean。这由打电话的人决定 它希望如何管理对该引用的访问。通常是一个网络 应用程序将把引用存储在HttpSession或 用于后续访问的应用程序范围(ServletContext)范围 以及: 别忘了,在你的案例中,我们处理的是两种类型的会话: bean会话和web会话。前者确保一旦你 请求一个有状态bean,它的标识在该bean中保持不变 用户会话。但是当你使用后者时,你有一个网络会话 bean会话的顶部。以确保从中访问相同的bean 2个不同的JSP(或者在重新加载时),需要存储 将bean的标识放入web会话范围
所以你实际上是对的。当您想要使用您的实例时,您必须使用ManagedBean在其他地方检索它,因为EJB实例与此会话上下文相关联。因此,如果您想简化它并确保EJB在每个会话中只存在一次,那么可以使用CDI并用
@javax.enterprise.context.SessionScoped
对EJB本身进行附加注释;是的,你混淆了不同的概念,也混淆了不同的API。。。
我宁愿使用@Injectover@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;
}
当你说“现在当我使用EJB_B”时,你是什么意思?您是如何验证它不是同一个实例的?当我建立EJB_B并查看EJB_a的属性(例如字符串属性)时,EJB_a bean的属性与托管bean实例化的EJB_a的属性不同;在另一个ManagedBean或Java客户机中(远程查找)?EJB在何处实例化并不重要。它从来都不起作用。我试过了。你能解释一下为什么我应该使用@Inject而不是@EJB吗?好的,关于这个主题的深入讨论在:[link]基本上区别因素是
@Inject
总是知道注入对象的范围,并且你确信注入的实例是一个托管实例(这样可以防止令人讨厌的远程bean序列化问题)。使用@Inject
您可以获得一个(有时是代理的)托管对象,使用@EJB
您可以获得一个资源,与简单的JNDI查找没有太大区别。我使用EJB3.x已经有一段时间了,我终于发现了这一点。它最终帮助我“共享”跨bean的会话bean实例。如果没有这个,我发现自己在同一个bean中做了很多不相关的工作,并且因为它而变得缓慢和庞大。