@Inject和@EJB的区别是什么?

时间:2022-01-18 20:08:25

I'm currently learning the new Java EE 6 component models and am confused with the latest dependency injection mechanism. So here are my questions:

我目前正在学习新的Java EE 6组件模型,并与最新的依赖注入机制相混淆。下面是我的问题:

1) What is the difference between @Inject and @EJB

1 . @Inject和@EJB的区别是什么?

2) If I have a simple POJO that contains another POJOs (which one of them is the DAO code), what would be the better choice: @Inject or @EJB?

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

Can I mix @Inject and @EJB?

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

An example would be:

一个例子是:

  • ClassA implements InterfaceA and has an instance of ClassA_Adaptor

    ClassA实现了InterfaceA,并有一个ClassA_Adaptor实例。

  • ClassA_Adaptor implements InterfaceAB and has an instance of ClassB

    ClassA_Adaptor实现了InterfaceAB并有一个ClassB的实例。

  • ClassB implements InterfaceB and has an instance of ClassB_Adaptor and an instance DAO_ClassB

    ClassB实现了InterfaceB,并有一个ClassB_Adaptor实例和一个实例DAO_ClassB。

  • ClassB_Adaptor implements InterfaceB and has an instance of ClassC

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

  • ClassC implements InterfaceBC and has an instance of WebService_ClassC

    ClassC实现了InterfaceBC,并有一个WebService_ClassC的实例。

  • DAO_ClassB will use JPA 2.0 (@PersistenceContext)

    DAO_ClassB将使用JPA 2.0 (@PersistenceContext)

I'd like to inject all of them including the DAO and the WebService.

我想给他们所有的人,包括DAO和WebService。

3) Is it a bad approach to only use transactional for certain operations but not for all?

3)是否只对某些操作使用事务性而不是对所有操作使用事务性的方法不好?

As an example: Some methods in DAO_ClassB are your typical query, while other methods are "write" methods. Is it bad to not wrap the "READ" methods with transaction?

例如,DAO_ClassB中的一些方法是典型的查询,而其他方法是“写”方法。不将“读取”方法与事务打包是不好的吗?

To my understanding, the DAO_ClassB can be wrapped with transaction using @EJB (inject the DAO_ClassB and make all methods transactional). How can I control it?

根据我的理解,DAO_ClassB可以使用@EJB(注入DAO_ClassB并使所有方法都是事务性的)来包装。我怎么控制它?

Sorry if some of the questions are confusing because I know only bits and pieces of the Java EE 6 new component model.

不好意思,如果有些问题让人困惑,因为我只知道Java EE 6新组件模型的部分和部分。

3 个解决方案

#1


29  

  1. @EJB injects EJBs only, but @Inject can be used to inject POJOs rather than EJBs. However, @Inject requires that your archive be a BDA (contain beans.xml for EE 6, or implicitly in EE 7). @Inject also has additional CDI-specific capabilities (scopes, interceptors, etc.), but those capabilities incur extra overhead. Application servers have support for specifying @EJB bindings so that a deployer can choose the target EJB, but @Inject only allows the application developer to choose the target EJB (and it must exist in the application).

    @EJB只注入ejb,但是@Inject可以用来注入pojo而不是ejb。但是,@Inject要求您的存档是BDA(包含bean)。@Inject也有额外的特定于cdi的功能(作用域、拦截器等),但是这些功能需要额外的开销。应用程序服务器支持指定@EJB绑定,以便部署人员可以选择目标EJB,但是@Inject只允许应用程序开发人员选择目标EJB(并且它必须存在于应用程序中)。

  2. If the target is not an EJB, then you must not use @EJB.

    如果目标不是EJB,那么您就不能使用@EJB。

  3. It depends whether you're making multiple inter-related queries and then attempting to make business decisions. You need to understand isolation levels and take them into consideration, even for read-only operations.

    这取决于您是否正在进行多个相互关联的查询,然后尝试进行业务决策。您需要了解隔离级别并考虑它们,即使是只读操作。

#2


8  

From Adam Biens Weblog:

从亚当好博客:

You can use both annotations to inject EJBs. Start with @Inject and if you encounter any problems, switch to @EJB.

您可以使用这两个注释来注入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 {
}

On the other hand, the @EJB annotation allows you to pass additional information, which could be useful to reference remote EJBs, or EJBs which cannot be simple injected in the "Convention over Configuration" style:

另一方面,@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


5  

  1. @Inject is more general than EJB and is part of CDI specification. So if you want to use @Inject, you need an implementation of it in your server.

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

  2. For POJOs (not EJBs) you have to use @Inject.

    对于pojo(非ejb)必须使用@Inject。

#1


29  

  1. @EJB injects EJBs only, but @Inject can be used to inject POJOs rather than EJBs. However, @Inject requires that your archive be a BDA (contain beans.xml for EE 6, or implicitly in EE 7). @Inject also has additional CDI-specific capabilities (scopes, interceptors, etc.), but those capabilities incur extra overhead. Application servers have support for specifying @EJB bindings so that a deployer can choose the target EJB, but @Inject only allows the application developer to choose the target EJB (and it must exist in the application).

    @EJB只注入ejb,但是@Inject可以用来注入pojo而不是ejb。但是,@Inject要求您的存档是BDA(包含bean)。@Inject也有额外的特定于cdi的功能(作用域、拦截器等),但是这些功能需要额外的开销。应用程序服务器支持指定@EJB绑定,以便部署人员可以选择目标EJB,但是@Inject只允许应用程序开发人员选择目标EJB(并且它必须存在于应用程序中)。

  2. If the target is not an EJB, then you must not use @EJB.

    如果目标不是EJB,那么您就不能使用@EJB。

  3. It depends whether you're making multiple inter-related queries and then attempting to make business decisions. You need to understand isolation levels and take them into consideration, even for read-only operations.

    这取决于您是否正在进行多个相互关联的查询,然后尝试进行业务决策。您需要了解隔离级别并考虑它们,即使是只读操作。

#2


8  

From Adam Biens Weblog:

从亚当好博客:

You can use both annotations to inject EJBs. Start with @Inject and if you encounter any problems, switch to @EJB.

您可以使用这两个注释来注入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 {
}

On the other hand, the @EJB annotation allows you to pass additional information, which could be useful to reference remote EJBs, or EJBs which cannot be simple injected in the "Convention over Configuration" style:

另一方面,@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


5  

  1. @Inject is more general than EJB and is part of CDI specification. So if you want to use @Inject, you need an implementation of it in your server.

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

  2. For POJOs (not EJBs) you have to use @Inject.

    对于pojo(非ejb)必须使用@Inject。