Tak, możesz dowolnie mieszać zarówno CDI, jak i EJB i osiągnąć świetne rezultaty. Wygląda na to, że używasz @WebService
i @Schedule
, co jest dobrym powodem do dodania EJB do miksu.
Istnieje wiele nieporozumień, więc oto kilka ogólnych informacji na temat EJB i CDI, ponieważ odnoszą się do każdego z nich razem.
EJB> = CDI
Zauważ, że EJB to fasola CDI i dlatego mają wszystkie zalety CDI. Odwrotna sytuacja nie jest (jeszcze). Więc zdecydowanie nie nabieraj nawyku myślenia „EJB kontra CDI”, ponieważ ta logika naprawdę przekłada się na „EJB + CDI kontra CDI”, co jest dziwnym równaniem.
W przyszłych wersjach Java EE będziemy kontynuować ich dostosowywanie. Co dostosowanie środków jest umożliwienie ludziom robić to, co już może zrobić, po prostu bez @Stateful
, @Stateless
lub @Singleton
adnotacji na szczycie.
EJB i CDI w terminach wdrożenia
Ostatecznie EJB i CDI mają tę samą podstawową konstrukcję, że są komponentami proxy. Kiedy otrzymujesz odniesienie do fasoli EJB lub CDI, nie jest to prawdziwa fasola. Raczej przedmiot, który otrzymujesz, jest fałszywy (proxy). Kiedy wywołujesz metodę na tym fałszywym obiekcie, wywołanie trafia do kontenera, który wyśle wywołanie przez przechwytywacze, dekoratory itp., A także zajmie się wszelkimi transakcjami lub kontrolami bezpieczeństwa. Gdy to wszystko jest zrobione, wywołanie w końcu trafia do rzeczywistego obiektu, a wynik jest przesyłany z powrotem przez proxy do wywołującego.
Różnica polega tylko na tym, jak rozwiązany jest obiekt, który ma zostać wywołany. Przez „rozwiązany” rozumiemy po prostu, gdzie i jak kontener szuka rzeczywistej instancji do wywołania.
W CDI kontener wygląda w „zakresie”, który w zasadzie jest hashemem, który istnieje przez określony czas (na żądanie @RequestScoped
, na sesję HTTP @SessionScoped
, na aplikację @ApplicationScoped
, konwersację JSF @ConversationScoped
lub na implementację zakresu niestandardowego).
W EJB pojemnik sprawdza również hashmap, jeśli ziarno jest typu @Stateful
. @Stateful
Fasoli mogą również korzystać z żadnej z powyższych opisów zakresu powodując jej żyć i umierać z wszystkich innych ziaren w zakresie. W EJB @Stateful
jest zasadniczo fasolą „o dowolnym zakresie”. Jest @Stateless
to w zasadzie pula instancji - otrzymujesz instancję z puli na czas trwania jednego wywołania. Zasadniczo @Singleton
jest@ApplicationScoped
Tak więc na podstawowym poziomie wszystko, co można zrobić z ziarnem „EJB”, powinno być w stanie zrobić z ziarnem „CDI”. Pod kołdrą strasznie trudno je odróżnić. Cała instalacja hydrauliczna jest taka sama, z wyjątkiem sposobu rozwiązywania przypadków.
Obecnie nie są one takie same, jeśli chodzi o usługi, które kontener będzie oferował podczas wykonywania tego proxy, ale jak mówię, pracujemy nad tym na poziomie specyfikacji Java EE.
Uwaga dotycząca wydajności
Zignoruj wszelkie „lekkie” lub „ciężkie” obrazy mentalne, które możesz mieć. To wszystko marketing. Mają w większości ten sam projekt wewnętrzny. Rozdzielczość instancji CDI jest być może nieco bardziej złożona, ponieważ jest nieco bardziej dynamiczna i kontekstowa. W porównaniu z tym, rozdzielczość instancji EJB jest dość statyczna, głupia i prosta.
Z punktu widzenia implementacji w TomEE mogę powiedzieć, że różnica w wydajności między wywołaniem EJB a wywołaniem komponentu bean CDI jest prawie zerowa.
Domyślnie POJO, następnie CDI, a następnie EJB
Oczywiście nie używaj CDI ani EJB, gdy nie ma korzyści. Dodaj CDI, gdy zaczniesz chcieć zastrzyku, zdarzeń, przechwytywaczy, dekoratorów, śledzenia cyklu życia i tym podobnych. To jest większość czasu.
Poza tymi podstawami, istnieje szereg przydatnych usług kontenerowych masz tylko możliwość korzystania jeśli dokonać fasoli CDI również EJB dodając @Stateful
, @Stateless
lub @Singleton
na nim.
Oto krótka lista sytuacji, w których wyłamałem się z EJB.
Korzystanie z JAX-WS
Odsłanianie JAX-WS @WebService
. Jestem leniwy. Gdy @WebService
jest to również EJB, nie musisz go wymieniać i mapować jako serwletu w web.xml
pliku. To dla mnie praca. Dodatkowo mam możliwość korzystania z dowolnej innej funkcji wymienionej poniżej. Więc to dla mnie oczywiste.
Dostępne @Stateless
i @Singleton
tylko.
Korzystanie z JAX-RS
Udostępnianie zasobu JAX-RS za pośrednictwem @Path
. Nadal jestem leniwy. Gdy usługa RESTful jest również EJB, ponownie otrzymujesz automatyczne wykrywanie i nie musisz dodawać jej do Application
podklasy JAX-RS ani niczego podobnego. Poza tym mogę udostępnić dokładnie to samo ziarno, co @WebService
jeśli chcę, lub użyć dowolnej z wymienionych poniżej wspaniałych funkcji.
Dostępne @Stateless
i @Singleton
tylko.
Logika uruchamiania
Załaduj przy uruchomieniu przez @Startup
. Obecnie nie ma odpowiednika w CDI. W jakiś sposób przegapiliśmy dodanie czegoś w rodzaju AfterStartup
zdarzenia w cyklu życia kontenera. Gdybyśmy to zrobili, po prostu moglibyśmy mieć @ApplicationScoped
fasolkę, która nasłuchuje, a to byłoby w rzeczywistości takie samo jak @Singleton
with @Startup
. Jest na liście dla CDI 1.1.
Dostępne @Singleton
tylko dla.
Praca równoległa
@Asynchronous
wywołanie metody. Uruchamianie wątków jest niemożliwe w żadnym środowisku po stronie serwera. Zbyt wiele wątków to poważny zabójca wydajności. Ta adnotacja umożliwia zrównoleglenie czynności wykonywanych przy użyciu puli wątków kontenera. To jest niesamowite.
Dostępne @Stateful
, @Stateless
a @Singleton
.
Planowanie pracy
@Schedule
lub ScheduleExpression
jest w zasadzie cronem lub Quartz
funkcjonalnością. Również super. Większość pojemników po prostu używa do tego kwarcu pod pokrywami. Większość ludzi nie wie jednak, że planowanie pracy w Java EE jest transakcyjne! Jeśli zaktualizujesz bazę danych, a następnie zaplanujesz pracę i jedna z nich się nie powiedzie, obie zostaną automatycznie wyczyszczone. Jeśli EntityManager
połączenie utrwalania nie powiedzie się lub wystąpi problem z opróżnianiem, nie ma potrzeby rozplanowywania pracy. Tak, transakcje.
Dostępne @Stateless
i @Singleton
tylko.
Korzystanie z EntityManagers w transakcji JTA
Powyższa uwaga dotycząca transakcji wymaga oczywiście korzystania z usługi JTA
managed EntityManager
. Możesz ich używać ze zwykłym "CDI", ale bez transakcji zarządzanych przez kontener może to być naprawdę monotonne powielanie UserTransaction
logiki zatwierdzania / wycofywania.
Dostępny dla wszystkich komponentów Java EE tym CDI, JSF @ManagedBean
, @WebServlet
, @WebListener
, @WebFilter
, itd @TransactionAttribute
adnotacji jest jednak dostępna @Stateful
, @Stateless
a @Singleton
tylko.
Zarządzanie JTA EntityManager
EXTENDED
Udało EntityManager
pozwala zachować EntityManager
otwarty od JTA
transakcji i nie stracić danych w pamięci podręcznej. Dobra funkcja we właściwym czasie i miejscu. Używaj odpowiedzialnie :)
Dostępne @Stateful
tylko dla.
Łatwa synchronizacja
Kiedy potrzebujesz synchronizacji, adnotacje @Lock(READ)
i @Lock(WRITE)
są całkiem doskonałe. Umożliwia bezpłatne jednoczesne zarządzanie dostępem. Pomiń całą instalację wodociągową ReentrantReadWriteLock. W tym samym wiadrze jest @AccessTimeout
, który pozwala określić, jak długo wątek powinien czekać, aby uzyskać dostęp do instancji fasoli, zanim się zrezygnuje.
Dostępne @Singleton
tylko dla fasoli.