156
votes

I have found this question: What is the difference between @Inject and @EJB but I did not get any wiser. I have not done Java EE before nor do I have experience with dependency injection so I do not understand what I should use?

Is @EJB an old way of injecting? Is the injection done by the EJB container when using this annotation while using @Inject use the new CDI framework? Is that the difference and should I be using @Inject instead of @EJB if this is the case?

6

6 Answers

187
votes

The @EJB is used to inject EJB's only and is available for quite some time now. @Inject can inject any managed bean and is a part of the new CDI specification (since Java EE 6).

In simple cases you can simply change @EJB to @Inject. In more advanced cases (e.g. when you heavily depend on @EJB's attributes like beanName, lookup or beanInterface) than in order to use @Inject you would need to define a @Producer field or method.

These resources might be helpful to understand the differences between @EJB and @Produces and how to get the best of them:

Antonio Goncalves' blog:
CDI Part I
CDI Part II
CDI Part III

JBoss Weld documentation:
CDI and the Java EE ecosystem

StackOverflow:
Inject @EJB bean based on conditions

35
votes

@Inject can inject any bean, while @EJB can only inject EJBs. You can use either to inject EJBs, but I'd prefer @Inject everywhere.

16
votes

Update: This answer may be incorrect or out of date. Please see comments for details.

I switched from @Inject to @EJB because @EJB allows circular injection whereas @Inject pukes on it.

Details: I needed @PostConstruct to call an @Asynchronous method but it would do so synchronously. The only way to make the asynchronous call was to have the original call a method of another bean and have it call back the method of the original bean. To do this each bean needed a reference to the other -- thus circular. @Inject failed for this task whereas @EJB worked.

12
votes

Here is a good discussion on the topic. Gavin King recommends @Inject over @EJB for non remote EJBs.

http://www.seamframework.org/107780.lace

or

https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace

Re: Injecting with @EJB or @Inject?

  1. Nov 2009, 20:48 America/New_York | Link Gavin King

That error is very strange, since EJB local references should always be serializable. Bug in glassfish, perhaps?

Basically, @Inject is always better, since:

it is more typesafe,
it supports @Alternatives, and
it is aware of the scope of the injected object.

I recommend against the use of @EJB except for declaring references to remote EJBs.

and

Re: Injecting with @EJB or @Inject?

  1. Nov 2009, 17:42 America/New_York | Link Gavin King

    Does it mean @EJB better with remote EJBs?

For a remote EJB, we can't declare metadata like qualifiers, @Alternative, etc, on the bean class, since the client simply isn't going to have access to that metadata. Furthermore, some additional metadata must be specified that we don't need for the local case (global JNDI name of whatever). So all that stuff needs to go somewhere else: namely the @Produces declaration.

4
votes

It may also be usefull to understand the difference in term of Session Bean Identity when using @EJB and @Inject. According to the specifications the following code will always be true:

@EJB Cart cart1;
@EJB Cart cart2;
… if (cart1.equals(cart2)) { // this test must return true ...}

Using @Inject instead of @EJB there is not the same.

see also stateless session beans identity for further info

0
votes

Injection already existed in Java EE 5 with the @Resource, @PersistentUnit or @EJB annotations, for example. But it was limited to certain resources (datasource, EJB . . .) and into certain components (Servlets, EJBs, JSF backing bean . . .). With CDI you can inject nearly anything anywhere thanks to the @Inject annotation.