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

What is the use of InitialContext in Java EE over mappedName?

我不明白什么时候有人会使用 (new InitialContext()).lookup(....) 而不是

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

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

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

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

例如,Java EE 的 MVC 框架 JSF 支持自定义转换器和验证器。但是,由于疏忽,自定义 JSF ConverterValidator 不支持 @EJB,而它们有时可能需要调用业务服务调用。这在 JSF 2.3 中得到了解决,但在那之前,一种解决方法是通过 JNDI 获取 EJB — 虽然这相当笨拙,但有更简单的解决方法,另请参见 a.o How to inject @EJB, @PersistenceContext, @Inject, @Autowired, etc in @FacesConverter?

Bean Validation 也是如此,Java EE 的验证框架。在 1.1 版之前,自定义 ConstraintValidator 不支持 @EJB。另见 a.o。 JSF 2.0 validation in actionListener or action method.

JNDI 名称用于 EJB 的情况,而不是特定于供应商的。至少,这不是 Java EE 中指定的那样。然而,它特定于 EJB 的打包方式以及 EJB 客户端在应用程序中的位置。这个相关问题的答案解释了 JNDI 名称的组成方式以及您应该根据 EJB 客户端的位置使用哪个名称:.

简而言之,如果你能用@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