Jak porównać CDI i EJB? oddziaływać?

106

Trudno mi zrozumieć, jak te dwie osoby oddziałują na siebie i gdzie leży granica między nimi. Czy się pokrywają? Czy są między nimi zwolnienia?

Wiem, że istnieją adnotacje związane z obydwoma, ale nie udało mi się znaleźć pełnej listy obu z krótkimi opisami. Nie jestem pewien, czy pomogłoby to wyjaśnić, jak się różnią lub gdzie się pokrywają.

Naprawdę po prostu zdezorientowany. (Myślę, że) dość dobrze rozumiem EJB, wydaje mi się, że trudno mi zrozumieć, co dokładnie wnosi CDI do stołu i jak zastępuje lub wzmacnia to, co już oferuje EJB.

Tim
źródło
3
To pytanie zajmuje pierwsze miejsce w wyszukiwarce Google „EJB CDI
Difference

Odpowiedzi:

50

CDI: chodzi o wstrzykiwanie zależności. Oznacza to, że możesz wprowadzić implementację interfejsu w dowolnym miejscu. Ten obiekt może być czymkolwiek, nie może być powiązany z EJB. Oto przykład, jak wstrzyknąć generator losowy za pomocą CDI. Nie ma nic o EJB. Będziesz używać CDI, gdy chcesz wstrzyknąć usługi inne niż EJB, różne implementacje lub algorytmy (więc w ogóle nie potrzebujesz tam EJB).
EJB: rozumiesz i prawdopodobnie jesteś zdezorientowany @EJBadnotacją - umożliwia ona wprowadzenie implementacji do usługi lub cokolwiek innego. Główną ideą jest to, że klasa, do której wstrzykujesz, powinna być zarządzana przez kontener EJB. Wygląda na to, że CDI rozumie, czym jest EJB, więc na serwerze zgodnym z Java EE 6 w serwlecie możesz zapisać oba

@EJB EJBService ejbService;

i

@Inject EJBService ejbService;

to może sprawić, że będziesz zdezorientowany, ale to prawdopodobnie jedyna rzecz, która jest pomostem między EJB a CDI.

Kiedy mówimy o CDI, możesz wstrzyknąć inne obiekty do klas zarządzanych przez CDI (po prostu powinny być tworzone przez platformy obsługujące CDI).

Co jeszcze oferuje CDI ... Na przykład używasz Struts 2 jako frameworka MVC (tylko przykład) i jesteś tutaj ograniczony, nawet przy użyciu EJB 3.1 - nie możesz używać @EJBadnotacji w akcji Struts, nie jest zarządzany przez kontener. Ale kiedy dodasz wtyczkę Struts2-CDI, możesz tam napisać @Injectadnotację dla tej samej rzeczy (więc nie jest potrzebne więcej wyszukiwania JNDI). W ten sposób wzmacnia moc EJB, ale jak wspomniałem wcześniej, to, co wstrzykujesz z CDI - nie ma znaczenia, czy jest to związane z EJB, czy nie, i to jest jego moc.

PS. zaktualizowany link do przykładu

Maxym
źródło
Czy @EJB i @Inject są rzeczywiście równoważne funkcjonalnie? Myślę, że zdezorientowało mnie nakładanie się metod iniekcji między CDI i resztą zupy akronimów Java EE. Więcej czytania wydaje się wskazywać, że istnieje nadzieja na dopasowanie adnotacji.
Tim
@Maxym Kiedy używasz @ Inject, w jaki sposób możesz upewnić się, że @ Stateless lub jakikolwiek inny komponent EJB po stronie serwera nadal korzysta z funkcji, takich jak Pooling lub współbieżność, które są oferowane przez kontener. Mam nadzieję, że nie jest to oferowane przez CDI, prawda?
Bala,
1
@Bala: CDI nie oferuje pulowania ... spójrz na CDI z lub bez EJB3.1 , mam nadzieję, że odpowie na twoje pytanie ..
Maxym,
@KorayTugay: CDI to funkcja Java EE, więc każdy serwer zgodny z Java EE 6 ma ją (nie myli się Glassfish 3.0.1+, JBoss 6+ itp.) Możesz rzucić okiem na JBoss Weld, referencyjną implementację CDI, którą można użyć na przykład Tomcat ...
Maxym
191

Obecnie jest to rzeczywiście trochę zagmatwane, ponieważ w Javie EE jest teraz wiele modeli komponentów. Są to fasole zarządzane CDI , EJB3 i JSF .

CDI to nowy dzieciak w okolicy. CDI wyposażone fasola dependency injection, scopingi event bus. Ziarna CDI są najbardziej elastyczne pod względem wstrzykiwania i określania zakresu. Magistrala zdarzeń jest bardzo lekka i bardzo dobrze nadaje się do nawet najprostszych aplikacji internetowych. Oprócz tego CDI udostępnia również bardzo zaawansowaną funkcję o nazwie portable extensions, która jest rodzajem mechanizmu wtyczek dla dostawców w celu zapewnienia dodatkowej funkcjonalności dla Java EE, którą można udostępnić we wszystkich implementacjach (Glassfish, JBoss AS, Websphere itp.) .

Komponenty EJB3 zostały zmodernizowane ze starego modelu komponentów EJB2 * i były pierwszymi komponentami Java EE zarządzanymi za pomocą adnotacji. EJB3 fasoli wyposażone dependency injection, declarative transactions, declarative security, pooling, concurrency control, asynchronous executioni remoting.

Wstrzykiwanie zależności w ziarnach EJB3 nie jest tak elastyczne, jak w ziarnach CDI, a ziarna EJB3 nie mają koncepcji zakresu. Jednak ziarna EJB3 są domyślnie transakcyjne i łączone ** , dwie bardzo użyteczne rzeczy, które CDI zdecydowało się pozostawić w domenie EJB3. Pozostałe wymienione pozycje również nie są dostępne w CDI. EJB3 nie ma jednak własnej magistrali zdarzeń, ale ma specjalny typ ziarna do odsłuchiwania komunikatów; fasola sterowana wiadomością. Może to służyć do odbierania komunikatów z systemu Java Messaging System lub z dowolnego innego systemu wyposażonego w adapter zasobów JCA. Używanie pełnowartościowych komunikatów do prostych zdarzeń jest znacznie cięższe niż magistrala zdarzeń CDI, a EJB3 definiuje tylko odbiornik, a nie interfejs API producenta.

JSF Managed Beans istniało w Javie EE od czasu dołączenia JSF. One też posiadają dependency injectioni scoping. JSF Managed Beans wprowadziło koncepcję deklaratywnego określania zakresu. Początkowo zakresy były raczej ograniczone, aw tej samej wersji Java EE, w której komponenty bean EJB3 można było już deklarować za pomocą adnotacji, nadal trzeba było zadeklarować w formacie XML Managed Beans. Bieżąca wersja JSF Managed Beans jest również ostatecznie deklarowana za pomocą adnotacji, a zakresy są rozszerzane o zakres widoku i możliwość tworzenia niestandardowych zakresów. Zakres widoku, który zapamiętuje dane między żądaniami do tej samej strony, jest unikalną cechą JSF Managed Beans.

Poza zakresem widoku, niewiele jest jeszcze dla JSF Managed Beans w Java EE 6. Brakujący zakres widoku w CDI jest niefortunny, ponieważ w przeciwnym razie CDI byłby idealnym super zestawem tego, co oferuje JSF Managed Beans. Aktualizacja : W Javie EE 7 / JSF 2.2 dodano kompatybilny z CDI @ViewScoped , dzięki czemu CDI jest rzeczywiście doskonałym super zestawem. Aktualizacja 2 : W JSF2.3 komponenty bean zarządzane przez JSF zostały uznane za przestarzałe na rzecz komponentów bean zarządzanych przez CDI.

W przypadku EJB3 i CDI sytuacja nie jest tak jednoznaczna. Model komponentów i API EJB3 oferuje wiele usług, których CDI nie oferuje, więc zazwyczaj EJB3 nie może zostać zastąpiony przez CDI. Z drugiej strony CDI może być używany w połączeniu z EJB3 - np. Dodając obsługę zakresu do EJB.

Reza Rahman, członek grupy ekspertów i twórca implementacji CDI o nazwie CanDI, często sugerował, że usługi związane z modelem komponentu EJB3 można doposażyć w zestaw adnotacji CDI. Gdyby tak się stało, wszystkie zarządzane ziarna w Java EE mogłyby stać się fasolami CDI. Nie oznacza to, że EJB3 znika lub staje się przestarzały, ale tylko, że jego funkcjonalność zostanie ujawniona za pośrednictwem CDI, a nie za pośrednictwem własnych adnotacji EJB, takich jak @Stateless i @EJB.

Aktualizacja

David Blevins z TomEE i sławy OpenEJB bardzo dobrze wyjaśnia różnice i podobieństwa między CDI i EJB na swoim blogu: CDI, kiedy wyrwać się z EJB

* Chociaż jest to tylko wzrost numeru wersji, ziarna EJB3 były w większości zupełnie innym rodzajem ziarna: prostym pojo, które staje się „zarządzanym ziarnem” przez zastosowanie prostej pojedynczej adnotacji, w porównaniu z modelem w EJB2, gdzie waga ciężka i zbyt szczegółowy deskryptor wdrażania XML był wymagany dla każdego komponentu bean, oprócz tego, że był on wymagany do implementacji różnych bardzo ciężkich i w większości bezsensownych interfejsów komponentów.

** Bezstanowe komponenty bean sesji są zwykle łączone, stanowe komponenty bean sesji zwykle nie (ale mogą być). W przypadku obu typów pulowanie jest zatem opcjonalne, a specyfikacja EJB nie narzuca tego ani w żaden sposób.

Arjan Tijms
źródło
3
Jestem nieco zdezorientowany Twoimi stwierdzeniami, że „fasola EJB3 nie ma pojęcia określania zakresu” i że „EJB3 nie ma własnej magistrali zdarzeń”. Jak to pasuje do twierdzenia Davida Blevina, że „EJB to fasola CDI, a zatem mają wszystkie zalety CDI”? Czy coś się zmieniło w tym względzie od chwili, gdy napisałeś swoją odpowiedź, a David napisał swój wpis na blogu?
Chris
5
To z powodu być może nieco zagmatwanej koncepcji, że tak naprawdę nie ma "fasoli CDI", ale istnieją usługi stosowane do zarządzanych fasoli. Ze względu na dyskusję ludzie (a więc ja sam) nazywają je w każdym razie „fasolami CDI”. Przed CDI ziarna EJB nie miały wyraźnego zakresu. Jak wyjaśnia David, Stateful ma domyślnie dowolny zakres (a zatem żaden zakres w szczególności). Teraz z dostępnym CDI, fasola EJB może korzystać z zakresów dostarczonych przez CDI. Bez specyfikacji CDI, więc patrząc wyłącznie na specyfikację EJB, nie ma wyraźnych zakresów.
Arjan Tijms
1
Czy możesz wyjaśnić, co masz na myśli, mówiąc „istnieją usługi dotyczące zarządzanej fasoli”? Czy to oznacza, że ​​tak naprawdę nie ma czegoś takiego jak fasola CDI? Czy to tylko niektóre zapewniające dodatkowe funkcje w POJO - EJB - lub w zarządzanym ziarnie JSF? Podoba Ci się możliwość używania adnotacji Inject w zarządzanym komponencie Bean JSF?
Koray Tugay
3
@Chris w celu dalszego wyjaśnienia z perspektywy specyfikacji EJB, podjęliśmy celową decyzję od początku CDI, aby wymagać, aby implementacje EJB obsługiwały 100% funkcji CDI ustawionej na EJB. Każdy aspekt CDI działa na EJB z wyjątkiem zakresów, które musieliśmy ograniczyć tylko do fasoli Stateful.
David Blevins,
1
Należy zauważyć, że JSF 2.2 udostępnia teraz javax.faces.view.ViewScoped, rozszerzenie CDI, które jest zasadniczo portem zakresu widoku JSF do CDI. Dzięki temu CDI jest pełnym zamiennikiem zarządzanych fasoli JSF.
jdessey
-1

Albert Einstein: If you can't explain it simply, you don't understand it well enough

Ejbs i CDI są dość łatwe do zrozumienia.

Ejbs:

  1. Zawsze będzie opatrzony adnotacjami kwalifikatorami zakresu, na przykład @Stateless, @Stateful, @Request itp.
  2. Instancje Ejbs są kontrolowane przez środowisko Java EE i łączone. Obowiązkiem ram EE jest zapewnienie instancji dla konsumenta.

@Stateless

 public class CarMaker(){
    public void createCar(Specification specs){
        Car car = new Car(specs);
    }
}

CarMaker jest opatrzony adnotacją z określonym zakresem Ejbs, dlatego jest to Ejb

CDI:

  1. Nie zarządzane w całości przez platformę EE, instancje muszą być tworzone samodzielnie.
  2. To jest zawsze zależne. pozwól mi wyjaśnić „zależne” na przykładzie:

    class Specification { private String color; private String model; //- Getter and Setter }

SpecificationKlasa CDI, ponieważ nie jest opatrzone EJB zakresy, a także musi to zainicjowany przez nie kodu EE ram. Należy tu zauważyć, że ponieważ nie dodaliśmy adnotacji do Specificationklasy, domyślnie jest ona opatrzona @Dependentadnotacją.

@Dependent  <- By default added 
class Specification { ... }

Further reading: Musisz dowiedzieć się więcej między adnotacją zakresu Ejbs a adnotacją zakresu CDI, co jeszcze bardziej wyjaśni koncepcję

HA S
źródło
Einstein powiedział również: „Wszystko powinno być tak proste, jak to tylko możliwe, ale nie prostsze”, w tym miejscu można (należy) zamienić słowo „wykonane” na „wyjaśnione”.
Kukeltje