我有以下配置:
我的EAR的每个EJB-JAR中都有2个EJB业务服务,它们都是这样开发的:
@Remote
public interface ServiceAItf {
...
}
@Stateless
@Local
public class ServiceAImpl implements ServiceAItf {
...
}
在我的WAR中,我通过远程接口上的显式“InitialContext.lookup”访问EJB组件。
在我的EAR中,我对注射的最佳实践非常困惑,无论是在性能,架构等方面......
我有以下问题:
如您所见,我已在服务实现上声明了注释“@ Local”,而未定义本地接口。这是对的吗?至少我在部署时没有错误。但也许我应该使用“@ LocalBean”注释?我想“@ LocalBean”注释只是允许直接作为“Local” EJB调用实现,但你必须在代码中使用这样的实现:
@Stateless @本地 public class ServiceBImpl实现ServiceBItf { @EJB private ServiceAImpl serviceA; ... }
将一个EJB注入另一个EJB的最佳方法是什么? 它的工作原理如下:
@Stateless @本地 public class ServiceBImpl实现ServiceBItf { @EJB 私人服务at服务A; ... }
但是从我注意到的,注入的“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调用?
经过所有这些分析后,我得出以下结论:
你怎么看?这是对的吗?
答案 0 :(得分:22)
如您所见,我已在服务上声明了注释“@Local” 没有定义本地接口的实现。这是对的吗?
使用EJB 3.1,删除了对本地接口的要求。除非您明确需要,否则无需编写它们。
将一个EJB注入另一个EJB的最佳方法是什么?
在这里要写几件事:
使用Java EE 6,Java Enterprise已发生变化。新的JSR定义了一个所谓的托管bean (不要与JSF托管bean混淆)作为一种最小的组件,在依赖注入和生命周期管理方面仍然可以从容器中受益。这意味着:如果您有一个组件并且“只是”想要使用DI并让容器控制其生命周期,那么您 不需要来使用它。如果 - 并且仅当 - 您明确需要EJB功能(如事务处理,池化,钝化和群集),您将最终使用EJB。
这使得您的问题的答案分为三个部分:
答案 1 :(得分:0)
@Inject
注释用于java bean(POJO),而@EJB
注释用于企业java bean。当容器将@EJB
注释提供的ejb注入另一个bean时,它还控制ejb的生命周期,为无状态bean执行池化等等(当未注入将要注入的bean时,引用将为null) 。如果使用@Inject
注释CDI机制,只需查找并创建注入资源的实例,就像使用new运算符一样(如果将要注入的接口的实现不存在,则引用将为null)。您可以使用带@Inject
注释的限定符来选择注入接口的不同实现。