@Inject 和 @EJB 有啥区别

Posted

技术标签:

【中文标题】@Inject 和 @EJB 有啥区别【英文标题】:What is the difference between @Inject and @EJB@Inject 和 @EJB 有什么区别 【发布时间】:2011-08-18 21:17:00 【问题描述】:

我目前正在学习新的 Java EE 6 组件模型,但对最新的依赖注入机制感到困惑。所以这是我的问题:

1)@Inject 和@EJB 有什么区别

2) 如果我有一个包含另一个 POJO(其中一个是 DAO 代码)的简单 POJO,那么更好的选择是:@Inject 还是 @EJB?

我可以混合使用@Inject 和@EJB 吗?

一个例子是:

ClassA 实现 InterfaceA 并具有 ClassA_Adaptor 的一个实例

ClassA_Adaptor 实现 InterfaceAB 并且有一个 ClassB 的实例

ClassB 实现 InterfaceB 并具有 ClassB_Adaptor 的一个实例和一个 实例 DAO_ClassB

ClassB_Adaptor 实现 InterfaceB 并且有一个 ClassC 的实例

ClassC 实现 InterfaceBC 并具有 WebService_ClassC 的一个实例

DAO_ClassB 将使用 JPA 2.0 (@PersistenceContext)

我想注入所有这些,包括 DAO 和 WebService。

3) 仅对某些操作而不是全部使用事务性是一种不好的方法吗?

例如:DAO_ClassB 中的某些方法是您的典型查询,而其他方法是“写入”方法。不使用事务包装“READ”方法是不是很糟糕?

据我了解,DAO_ClassB 可以使用 @EJB 与事务一起包装(注入 DAO_ClassB 并使所有方法都具有事务性)。怎么控制?

抱歉,如果有些问题令人困惑,因为我只知道 Java EE 6 新组件模型的零碎部分。

【问题讨论】:

【参考方案1】:

    @EJB 仅注入 EJB,但 @Inject 可用于注入 POJO 而不是 EJB。但是,@Inject 要求您的存档是 BDA(包含 EE 6 的 beans.xml,或隐含在 EE 7 中)。 @Inject 还具有额外的 CDI 特定功能(范围、拦截器等),但这些功能会产生额外的开销。应用程序服务器支持指定@EJB 绑定,以便部署者可以选择目标EJB,但@Inject 只允许应用程序开发人员选择目标EJB(并且它必须存在于应用程序中)。

    如果目标不是 EJB,则不能使用 @EJB。

    这取决于您是否要进行多个相互关联的查询,然后再尝试做出业务决策。您需要了解隔离级别并将其考虑在内,即使对于只读操作也是如此。

【讨论】:

Bean 部署存档。这是一个包含 beans.xml 的 JAR。 使用@Inject 而不是@EJB 注入(本地、相同归档)EJB 的后果是什么? @Inject 版本将尊重 EJB 的范围。例如,使用@EJB 将 SFSB 注入 servlet 是没有意义的,因为每个请求只存在一个 SFSB。使用 @Inject 将 @SessionScoped SFSB 注入 servlet 意味着您有一个 CDI 代理,可以根据需要为每个会话创建一个新的 SFSB。 如果你用@Inject 注入一个 SLSB,EJB 容器仍然会控制 bean 的生命周期? 是的,CDI 容器知道一个类型是否是 EJB 接口,所以它仍然会与 EJB 容器协调以获得一个 EJB 代理,这使得 EJB 容器可以控制实际的 bean 生命周期,并且然后 CDI 容器将根据需要用 CDI 代理包装 EJB 代理(例如,上下文代理对无状态 bean 没有意义,但对有状态 bean 有意义)。【参考方案2】:

来自Adam Biens Weblog:

您可以使用这两种注解来注入 EJB。从@Inject 开始,如果遇到任何问题,请切换到@EJB。

@Inject does not have any methods / attributes--it is just a plain annotation:


@Target(value = ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.FIELD)
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface Inject 

另一方面,@EJB 注释允许您传递附加信息,这些信息对于引用远程 EJB 或无法以“约定优于配置”样式简单注入的 EJB 很有用:

@Target(value = ElementType.TYPE, ElementType.METHOD, ElementType.FIELD)
@Retention(value = RetentionPolicy.RUNTIME)
public @interface EJB 

    public String name() default "";

    public String beanName() default "";

    public Class beanInterface() default Object.class;

    public String mappedName() default "";

【讨论】:

投票反对从该博客 adam-bien.com/roller/abien/entry/inject_vs_ejb 逐字复制答案而没有给予信用。 我认为这是最好的答案。我在分析器中添加了对原始帖子的引用。 现在死链接:(【参考方案3】:

    @Inject 比 EJB 更通用,是 CDI 规范的一部分。所以如果你想使用@Inject,你需要在你的服务器中实现它。

    对于 POJO(不是 EJB),您必须使用 @Inject。

【讨论】:

以上是关于@Inject 和 @EJB 有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

javax.inject.Inject 和 com.google.inject.Inject 有啥区别?

dagger2 中的@Provide 和@Inject 有啥区别?

CDI 中的@ApplicationScoped 和@Singleton 作用域有啥区别?

DAO 和存储库模式有啥区别?

JPA 和 JDO 规范有啥区别?

springmvc和其他mvc框架有啥区别?