Czy powinienem używać @EJB czy @Inject

148

Znalazłem to pytanie: Jaka jest różnica między @Inject a @EJB, ale nie zrozumiałem nic mądrzejszego. Nie robiłem wcześniej Java EE ani nie mam doświadczenia z wstrzykiwaniem zależności, więc nie rozumiem, czego powinienem użyć?

Czy @EJB to stary sposób wstrzykiwania? Czy wstrzyknięcie jest wykonywane przez kontener EJB podczas korzystania z tej adnotacji podczas korzystania z @Inject przy użyciu nowej struktury CDI? Czy na tym polega różnica i czy powinienem używać @Inject zamiast @EJB, jeśli tak jest?

Lucky Luke
źródło

Odpowiedzi:

178

@EJBSłuży do wstrzykiwania EJB tylko i jest dostępny już od jakiegoś czasu. @Injectmoże wstrzyknąć dowolny zarządzany komponent bean i jest częścią nowej specyfikacji CDI (od wersji Java EE 6).

W prostych przypadkach możesz po prostu zmienić @EJBna @Inject. W bardziej zaawansowanych przypadkach (np. Gdy w dużym stopniu polegasz na @EJBatrybutach, takich jak beanName, lookuplub beanInterface) @Inject, musisz zdefiniować @Producerpole lub metodę.

Te zasoby mogą być pomocne w zrozumieniu różnic między @EJBi @Producesoraz w jaki sposób można je najlepiej wykorzystać:

Blog Antonio Goncalvesa:
CDI Część I
CDI Część II
CDI Część III

Dokumentacja JBoss Weld:
CDI i ekosystem Java EE

StackOverflow:
Inject @EJB bean na podstawie warunków

Piotr Nowicki
źródło
4
dlaczego @EJBdziała w przypadku wtrysku okrągłego (jedna fasola pojedyncza, a druga wymaga odniesienia do siebie)? (w nawiązaniu do mojej odpowiedzi poniżej - nie jestem pewien, czy robię dobrze, przechodząc na @EJB)
nekromanta
2
ponieważ nie wstrzykujesz implementacji, ale serwer proxy, który wstawia się do implementacji. dzięki temu uzyskujesz zalety „późnego wiązania” i innych funkcji kontenera.
go
33

@Injectmoże wstrzyknąć dowolną fasolę, podczas gdy @EJBmoże wstrzyknąć tylko EJB. Możesz użyć albo do wstrzyknięcia EJB, ale wolałbym @Injectwszędzie.

Bozho
źródło
1
Co dokładnie robi zastrzyk, gdy używamy @Inject? Kontener JavaEE? Czy może wstrzyknąć POJO?
Koray Tugay
3
z CDI jest to kontener CDI (dołączony do kontenera JavaEE)
Bozho
16

Aktualizacja: ta odpowiedź może być nieprawidłowa lub nieaktualna. Szczegółowe informacje można znaleźć w komentarzach.

Przeszedłem z @Injectna @EJBbo @EJBpozwala na okrężne wtryski, podczas gdy @Injectwymiotuje na to.

Szczegóły: Musiałem @PostConstructwywołać @Asynchronousmetodę, ale zrobiłaby to synchronicznie. Jedynym sposobem, aby wywołanie asynchroniczne było spowodowanie, aby wywołanie pierwotne było metodą innego komponentu bean i wywołało z powrotem metodę pierwotnego komponentu bean. Aby to zrobić, każda fasola potrzebowała odniesienia do drugiej - a więc okrągłej. @Injectnie udało się wykonać tego zadania, podczas gdy @EJBpracował.

nekromanta
źródło
@MartijnBurger Nie mam pod ręką kodu ani środowiska Java EE. Po prostu utwórz 2 klasy Java i umieść @Injectje w swoich publicznych polach. Jeśli to zadziała, moja odpowiedź jest błędna. Jeśli to nie zadziała, moja odpowiedź jest jak dotąd poprawna. Następny Zmiana @Injectdo @EJB(i ewentualnie opisywanie klasach siebie? Zapomnę.). Wtedy cykliczne wzajemne wtryskiwanie powinno działać dobrze. Dlatego przełączyłem się z @Injectna @EJB. Mam nadzieję, że to ma sens.
nekromanta
Utworzyłem dwa pojo i wstrzyknąłem sobie je do siebie. Działa bez problemów w mojej konfiguracji (WildFly 8.2 = CDI 1.2)
Martijn Burger
1
Dzięki @MartijnBurger, potwierdzę to, aw międzyczasie dodaję ostrzeżenie do mojej odpowiedzi.
nekromanta
Nie jestem pewien, co chciałeś osiągnąć, ale prawdopodobnie robi to dokładnie to, czego chciałeś i bez zależności cyklicznej. tomee.apache.org/examples-trunk/async-postconstruct/README.html . Również asynchroniczne zdarzenia CDI mogą być bardziej przejrzystym rozwiązaniem (w zależności od wymagań).
stycznia
12

Oto dobra dyskusja na ten temat. Gavin King zaleca @Inject over @EJB dla niezdalnych EJB.

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

lub

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

Re: Wstrzykiwanie za pomocą @EJB lub @Inject?

  1. Lis 2009, 20:48 Ameryka / Nowy_Jork | Połącz Gavina Kinga

Ten błąd jest bardzo dziwny, ponieważ lokalne odwołania EJB powinny być zawsze możliwe do serializacji. Może błąd w szklistej rybce?

Zasadniczo @Inject jest zawsze lepszy, ponieważ:

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

Odradzam używanie @EJB poza deklarowaniem odniesień do zdalnych EJB.

i

Re: Wstrzykiwanie za pomocą @EJB lub @Inject?

  1. Lis 2009, 17:42 America / New_York | Połącz Gavina Kinga

    Czy to oznacza, że ​​@EJB jest lepsze ze zdalnymi EJB?

W przypadku zdalnego EJB nie możemy zadeklarować metadanych, takich jak kwalifikatory, @Alternative itp. W klasie bean, ponieważ klient po prostu nie będzie miał dostępu do tych metadanych. Ponadto należy określić dodatkowe metadane, których nie potrzebujemy dla przypadku lokalnego (globalna nazwa JNDI czegoś). Więc wszystko to musi iść gdzie indziej: mianowicie deklaracja @Produces.

John Manko
źródło
1
Chociaż może to teoretycznie odpowiedzieć na pytanie, lepiej byłoby zawrzeć tutaj zasadnicze części odpowiedzi i podać link do odniesienia. W ten sposób ta odpowiedź byłaby cenna nawet teraz, gdy łącze nie działa.
Mifeet
4

Przydatne może być również zrozumienie różnicy w terminach tożsamości Session Bean podczas korzystania z @EJB i @Inject. Zgodnie ze specyfikacją następujący kod zawsze będzie true:

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

Używanie @Inject zamiast @EJB nie jest takie samo.

Aby uzyskać więcej informacji, zobacz także tożsamość bezstanowych ziaren sesji

rozpoznać
źródło
0

Na przykład iniekcja istniała już w Javie EE 5 z adnotacjami @Resource, @PersistentUnit lub @EJB. Ale było ograniczone do pewnych zasobów (źródło danych, EJB…) i do pewnych komponentów (serwlety, EJB, komponent bean JSF…). Dzięki CDI możesz wstrzyknąć prawie wszystko w dowolnym miejscu dzięki adnotacji @Inject.

javierZanetti
źródło