@Inject、@EJB、@Local、@Remote、@LocalBean等:困惑?
我有以下配置:
- 一个 GF 上的 1 个 EAR,其中包含 2 个带有 EJB 组件的 EJB-JAR。
- 1 另一台 Glassfish 服务器(=>其他 JVM)上的 WAR,其中包含访问 EJB 组件的 Web 组件。
我在 EAR 的每个 EJB-JAR 中都有 2 个 EJB 业务服务,它们都是这样开发的:
@Remote
public interface ServiceAItf {
...
}
@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
...
}
在我的 WAR 中,我通过远程接口上的显式“InitialContext.lookup”访问 EJB 组件。
在我的EAR中,我对注入的最佳实践感到非常困惑,在性能,体系结构等方面...
我有以下问题:
-
如您所见,我已经在服务实现上声明了注释“@Local”,而没有定义本地接口。这是正确的吗?至少我在部署时没有错误。但也许我应该使用“@LocalBean”注释来代替?我假设“@LocalBean”注释只是允许直接调用实现作为“本地”EJB,但是您必须在代码中使用实现,如下所示:
@Stateless @Local公共类 ServiceBImpl 实现 ServiceBItf { @EJB private ServiceAImpl serviceA; ... }
-
将一个 EJB 注入另一个 EJB 的最佳方法是什么?它的工作原理如下:
@Stateless @Local公共类 ServiceBImpl 实现 ServiceBItf { @EJB private ServiceAItf serviceA; ... }
但从我注意到的情况来看,注入的“serviceA”是远程代理,而它位于同一EAR文件的同一JVM中。因此,我认为会对性能产生影响。这就是为什么我试图像这样注入服务:
@Stateless
@Local
public class ServiceBImpl implements ServiceBItf {
@Inject
private ServiceAItf serviceA;
...
}
但它在GF中不起作用,我有以下例外:
WELD-001408 Unsatisfied dependencies for type [...] ...
然后,我尝试创建一个本地接口,当两个服务都有效时,通过注释“@Inject”进行注入。
即使我创建了这样的本地接口,该服务也不会通过注释“@Inject”注入,而是空的:
@Local
public interface ServiceALocalItf {
...
}
我读过很多文章,强烈建议在本地调用时使用“@Inject”而不是“@EJB”。这就引出了以下问题:在这种情况下,建议(或直接使用)“@Local”EJB 调用?
经过所有这些分析,我得出以下结论:
- 对于每个服务,我创建一个“@Local”和一个“@Remote”接口。
- 从 WAR 到 EAR 的 EJB-JAR,对远程接口进行 JNDI 查找。
- 从 EJB-JAR 到 EJB-JAR,通过“@EJB”注入到本地接口。
- 对于同一 EJB-JAR 中的两个服务,通过“@Inject”注入到本地接口。
对此,你怎么看?这是正确的吗?