【问题标题】: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 新组件模型的零碎部分。

【问题讨论】:

    标签: jpa-2.0 java-ee-6 ejb-3.1


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

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

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

    【讨论】:

    • 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 "";
    }
    

    【讨论】:

    【解决方案3】:
    1. @Inject 比 EJB 更通用,是 CDI 规范的一部分。所以如果你想使用@Inject,你需要在你的服务器中实现它。

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

    【讨论】:

      猜你喜欢
      • 2011-11-25
      • 2020-01-09
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 2016-10-22
      • 2014-12-31
      • 1970-01-01
      • 2011-12-20
      相关资源
      最近更新 更多