@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 有啥区别?