Java EE中的InitialContext比mappedName有什么用?

时间:2015-11-29 20:48:13

标签: java-ee dependency-injection ejb initial-context

我不明白有人会使用(new InitialContext()).lookup(....)代替

@Stateless(mappedName="A1Global")
public class A1 implements A { ... }

@EJB(mappedName="A1Global")
private A a;

mappedName 的后一种方法是否有任何缺点?我还注意到JNDI名称可能是特定于供应商的,复杂且不必要的长。

1 个答案:

答案 0 :(得分:3)

通过JNDI抓取EJB在不受依赖注入容器管理的类中可能很有用,因此@EJB只能在其中工作。然而,这些是罕见的情况,通常是由与您要使用@EJB的客户端框架相关的规范中的错误或疏忽引起的,并且应该在较新版本中报告,讨论和解决该客户端框架,以便最终可以使用@EJB

例如,Java EE的MVC框架JSF支持自定义转换器和验证器。但是,由于疏忽,自定义JSF @EJBConverter不支持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可能会发生同样的情况。