我不明白有人会使用(new InitialContext()).lookup(....)
代替
@Stateless(mappedName="A1Global")
public class A1 implements A { ... }
@EJB(mappedName="A1Global")
private A a;
mappedName 的后一种方法是否有任何缺点?我还注意到JNDI名称可能是特定于供应商的,复杂且不必要的长。
答案 0 :(得分:3)
通过JNDI抓取EJB在不受依赖注入容器管理的类中可能很有用,因此@EJB
只能在其中工作。然而,这些是罕见的情况,通常是由与您要使用@EJB
的客户端框架相关的规范中的错误或疏忽引起的,并且应该在较新版本中报告,讨论和解决该客户端框架,以便最终可以使用@EJB
。
例如,Java EE的MVC框架JSF支持自定义转换器和验证器。但是,由于疏忽,自定义JSF @EJB
或Converter
不支持Validator
,而他们有时可能需要调用业务服务调用。这在JSF 2.3中得到了解决,但直到那时,一个解决方法是通过JNDI获取EJB - 虽然相当笨拙,但有更简单的解决方法,另请参阅a.o How to inject @EJB, @PersistenceContext, @Inject, @Autowired, etc in @FacesConverter?
同样的故事发生在Java验证框架的Bean Validation上。在版本1.1之前,自定义@EJB
不支持ConstraintValidator
。另见a.o. JSF 2.0 validation in actionListener or action method
如果EJB不是特定于供应商的,则JNDI名称。至少,这不是Java EE中指定的那样。然而,它特定于EJB的打包方式以及EJB客户端在应用程序中的位置。这个相关问题的答案解释了如何组成JNDI名称以及您应该使用哪个名称,具体取决于EJB客户端的位置:Inject EJB bean from JSF managed bean programmatically。
简而言之,如果您可以使用@EJB
,那么请务必使用它。如果你不能,那么首先要研究你是否以正确的方式做事。有时,人们试图在一个绝对没有意义的地方抓住EJB。如果您可以确认您不是唯一在使用@EJB
以达到所需功能要求时遇到问题,那么请向相关客户端框架报告问题。很可能他们会在意图的地方添加@EJB
支持。
也就是说,如果您的环境支持CDI,那么您需要知道现在建议将@EJB
迁移到@Inject
。在Java EE 6/7中,它可以很好地期待一个角落的情况(在自我中循环注入EJB)。 CDI的目标是将Java EE框架中的所有各种依赖注入机制统一到一个API中。例如,JSF已经计划在将来的Java EE版本中弃用其@ManagedBean
/ @ManagedProperty
而转而使用@Named
/ @Inject
。另见a.o. Backing beans (@ManagedBean) or CDI Beans (@Named)? @EJB
支持@Inject
可能会发生同样的情况。