我不明白什么时候有人会使用(new InitialContext()).lookup(....)
而不是
@Stateless(mappedName="A1Global")
public class A1 implements A { ... }
@EJB(mappedName="A1Global")
private A a;
后一种方法与mappedName有什么缺点吗?我还注意到 JNDI 名称可能是特定于供应商的、复杂的和不必要的长。
我不明白什么时候有人会使用(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 支持自定义转换器和验证器。但是,由于疏忽,@EJB
在自定义 JSF 中不支持,Converter
或者Validator
有时它们可能需要调用业务服务调用。这在 JSF 2.3 中得到了解决,但在那之前,一种解决方法是通过 JNDI 获取 EJB——虽然这相当笨拙,但有更简单的解决方法,另请参见 ao如何注入 @EJB、@PersistenceContext、@Inject、@Autowired、 @FacesConverter 等?
Java EE 的验证框架 Bean Validation 也是如此。直到版本 1.1 才@EJB
在自定义中支持。ConstraintValidator
另请参阅actionListener 或 action 方法中的 ao JSF 2.0 验证。
JNDI 名称用于 EJB 不是特定于供应商的。至少,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
另请参见支持 bean (@ManagedBean) 或 CDI Bean (@Named)?@EJB
赞成的情况也可能发生同样的情况@Inject
。