167

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?

BuZZ-dEE
  • 6,075
  • 12
  • 66
  • 96
LuckyLuke
  • 47,771
  • 85
  • 270
  • 434

9 Answers9

198

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

homaxto
  • 5,428
  • 8
  • 37
  • 53
Piotr Nowicki
  • 17,914
  • 8
  • 63
  • 82
  • 4
    why does `@EJB` work for circular injection (one singleton bean and another bean needing a reference to each other)? (with reference to my answer below - i am not sure if i am doing the right thing by switching to `@EJB`) – necromancer May 12 '13 at 08:30
  • 2
    because you're not injecting the implementation, but a proxy that interposes on the implementation. because of this, you get the advantages of "late binding" and other container features. – him Oct 19 '18 at 21:37
38

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

Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
16

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.

necromancer
  • 23,916
  • 22
  • 68
  • 115
  • @MartijnBurger I don't have the code handy, nor a Java EE environment handy. Just create 2 Java classes and `@Inject` them into each other's public fields. If that works then my answer is wrong. If that does not work, then my answer is correct so far. Next change the `@Inject` to `@EJB` (and possibly annotate the classes themselves? I forget.). Then the cyclic mutual injection should work fine. That's why I switched from `@Inject` to `@EJB`. Hope this makes sense. – necromancer Feb 10 '15 at 12:13
  • I created two pojo's and injected the pojo's into each other. Works without problems in my config (WildFly 8.2 = CDI 1.2) – Martijn Burger Feb 10 '15 at 13:09
  • 1
    Thanks @MartijnBurger, I'll confirm that, and in the meanwhile add a note of caution to my answer. – necromancer Feb 11 '15 at 07:39
  • No exactly sure what you wanted to achieve, but this probably does exactly what you wanted and without a circular dependency. http://tomee.apache.org/examples-trunk/async-postconstruct/README.html. Also asynchronous CDI events could be a cleaner way to go (depending on the requirements). – JanM Sep 05 '15 at 14:33
12

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.

John Manko
  • 1,828
  • 27
  • 51
  • 1
    While this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. That way this answer would be valuable even now when the link is dead. – Mifeet Dec 12 '15 at 16:28
  • 1
    https://web.archive.org/web/20140812065624/http://www.seamframework.org/107780.lace – John Manko Feb 19 '16 at 15:54
5

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

ken
  • 471
  • 9
  • 19
0

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.

javierZanetti
  • 288
  • 4
  • 17
0

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.

0

@Inject is a documented annotation, so IDEA knows how to process it and you can see a different colours in a code. @EJB - no.

zenon
  • 61
  • 1
  • 2
-1

use @EBJ with EJB's. This is for creating a separated business logic layer that is independent of the types of interfaces (Tiered Applications).

This (used correctly) allows the business logic to be modified and deployed separately from the (multiple) user-interface applications without loss of availability.

Chris
  • 194
  • 6