Przede wszystkim pozwolę sobie wyjaśnić:
Definicja zarządzanej fasoli : ogólnie zarządzana fasola to obiekt, którego cyklem życia (budowa, zniszczenie itp.) Zarządza pojemnik.
W Java ee mamy wiele kontenerów, które zarządzają cyklem życia ich obiektów, takich jak kontener JSF, kontener EJB, kontener CDI, kontener serwletów itp.
Wszystkie te kontenery działają jakby niezależnie, uruchamiają się podczas inicjalizacji serwera aplikacji i skanują klasy wszystkich artefaktów, w tym plików jar, ejb-jar, war i ear, w czasie wdrażania oraz gromadzą i przechowują niektóre metadane na ich temat, a następnie gdy potrzebujesz obiektu klasy w czasie wykonywania dadzą ci instancje tych klas, a po zakończeniu zadania, zniszczą je.
Możemy więc powiedzieć, że mamy:
- Fasola zarządzana przez JSF
- Fasola zarządzana przez CDI
- Fasola zarządzana przez EJB
- Nawet serwlety są zarządzanymi komponentami bean, ponieważ są tworzone i niszczone przez kontener, który jest kontenerem serwletów.
Więc kiedy widzisz słowo Managed Bean, powinieneś zapytać o kontekst lub typ tego (JSF, CDI, EJB itp.)
Następnie możesz zapytać, dlaczego mamy wiele z tych kontenerów: AFAIK, faceci z Java EE chcieli mieć framework do wstrzykiwania zależności, ale nie mogli zebrać wszystkich wymagań w jednej specyfikacji, ponieważ nie mogli przewidzieć przyszłych wymagań i stworzyli EJB 1.0, a następnie 2.0, potem 3.0, a teraz 3.1, ale celem EJB było tylko spełnienie niektórych wymagań (transakcje, rozproszony model komponentów itp.).
W tym samym czasie (równolegle) zdali sobie sprawę, że muszą również obsługiwać JSF, a następnie stworzyli fasolę zarządzaną przez JSF i inny kontener dla fasoli JSF i uznali to za dojrzały kontener DI, ale nadal nie był to kompletny i dojrzały kontener.
Potem Gavin King i kilku innych sympatycznych gości;) stworzył CDI, który jest najbardziej dojrzałym kontenerem DI, jaki widziałem. CDI (zainspirowane przez Seam2, Guice i Spring) zostało stworzone, aby wypełnić lukę między JSF i EJB i wieloma innymi przydatnymi rzeczami, takimi jak wtrysk pojo, metody producenta, przechwytywacze, dekoratory, integracja SPI, bardzo elastyczny itp. I może nawet to zrobić co robią fasola zarządzana przez EJB i JSF, możemy mieć tylko jeden dojrzały i potężny kontener DI. Ale z pewnych wstecznej kompatybilności i powodów politycznych, faceci Java EE chcą je zachować !!!
Tutaj możesz znaleźć różnice i przypadki użycia dla każdego z tych typów:
Fasola zarządzana JSF, fasola CDI i EJB
JSF został początkowo opracowany z własnym mechanizmem zarządzanego komponentu bean i wstrzykiwania zależności, który został ulepszony dla JSF 2.0 w celu uwzględnienia komponentów bean opartych na adnotacjach. Kiedy CDI został wydany z Java EE 6, był uważany za zarządzany framework bean dla tej platformy i oczywiście EJB przestarzał je wszystkie, ponieważ były dostępne od ponad dekady.
Problem polega oczywiście na tym, aby wiedzieć, którego użyć i kiedy ich używać.
Zacznijmy od najprostszej, zarządzanej fasoli JSF.
Fasola zarządzana JSF
Krótko mówiąc, nie używaj ich, jeśli tworzysz dla Java EE 6 i używasz CDI. Zapewniają prosty mechanizm wstrzykiwania zależności i definiowania komponentów bean wspierających dla stron internetowych, ale są znacznie mniej wydajne niż fasole CDI.
Można je zdefiniować za pomocą @javax.faces.bean.ManagedBean
adnotacji, która przyjmuje opcjonalny parametr nazwy. Tej nazwy można użyć do odniesienia do ziarna ze stron JSF.
Zakres można zastosować do komponentu bean przy użyciu jednego z różnych zakresów zdefiniowanych w javax.faces.bean
pakiecie, które obejmują żądanie, sesję, aplikację, widok i niestandardowe zakresy.
@ManagedBean(name="someBean")
@RequestScoped
public class SomeBean {
....
....
}
Ziarna JSF nie mogą być mieszane z innymi rodzajami ziaren bez jakiegoś ręcznego kodowania.
Fasola CDI
CDI to platforma do zarządzania komponentami bean i wstrzykiwania zależności, która została wydana jako część Java EE 6 i zawiera kompletne, kompleksowe narzędzie do zarządzania komponentami bean. Fasola CDI jest znacznie bardziej zaawansowana i elastyczna niż prosta fasola zarządzana przez JSF. Potrafią posługiwać się przechwytywaczami, zakresem konwersacji, zdarzeniami, bezpiecznym wtryskiem typu, dekoratorami, stereotypami i metodami producenta.
Aby wdrożyć komponenty bean CDI, należy umieścić plik o nazwie beans.xml w folderze META-INF w ścieżce klas. Gdy to zrobisz, każda fasola w opakowaniu stanie się ziarnem CDI. W CDI jest wiele funkcji, zbyt wiele, aby je tutaj omówić, ale jako szybkie odniesienie do funkcji podobnych do JSF, możesz zdefiniować zakres komponentu bean CDI za pomocą jednego z zakresów zdefiniowanych w javax.enterprise.context
pakiecie (a mianowicie żądanie, rozmowa , zakresy sesji i aplikacji). Jeśli chcesz użyć fasoli CDI ze strony JSF, możesz nadać jej nazwę za pomocą javax.inject.Named
adnotacji. Aby wstrzyknąć ziarno do innego ziarna, należy opisać pole javax.inject.Inject
adnotacją.
@Named("someBean")
@RequestScoped
public class SomeBean {
@Inject
private SomeService someService;
}
Automatyczne wstrzykiwanie, takie jak zdefiniowane powyżej, można kontrolować za pomocą kwalifikatorów, które mogą pomóc w dopasowaniu określonej klasy, którą chcesz wstrzyknąć. Jeśli masz wiele typów płatności, możesz dodać kwalifikator określający, czy jest on asynchroniczny, czy nie. Chociaż możesz użyć @Named
adnotacji jako kwalifikatora, nie powinieneś, ponieważ jest ona przewidziana dla ujawniania fasoli w EL.
CDI obsługuje wstrzykiwanie ziaren o niedopasowanych zakresach za pomocą serwerów proxy. Z tego powodu można wstrzyknąć komponent bean o zasięgu żądania do komponentu bean o zasięgu sesji, a odwołanie będzie nadal ważne dla każdego żądania, ponieważ dla każdego żądania serwer proxy ponownie łączy się z aktywnym wystąpieniem komponentu bean o zasięgu żądania.
CDI obsługuje również przechwytywacze, zdarzenia, nowy zakres konwersacji i wiele innych funkcji, co czyni go znacznie lepszym wyborem niż fasolki zarządzane przez JSF.
EJB
EJB są starsze niż fasole CDI i są w pewnym sensie podobne do fasoli CDI, a pod innymi względami bardzo się różnią. Przede wszystkim różnice między fasolami CDI i EJB polegają na tym, że EJB to:
- Transakcyjne
- Zdalnie lub lokalnie
- Potrafi pasywować stanowe fasole, zwalniając zasoby
- Potrafi korzystać z timerów
- Może być asynchroniczny
Te dwa typy EJB nazywane są bezpaństwowymi i stanowymi. Bezstanowe komponenty EJB można traktować jako bezpieczne wątkowo elementy bean jednorazowego użytku, które nie zachowują żadnego stanu między dwoma żądaniami sieci Web. Stanowe EJB zachowują stan i mogą być tworzone i pozostawać w pobliżu tak długo, jak są potrzebne, dopóki nie zostaną usunięte.
Definiowanie EJB jest proste, wystarczy dodać adnotację javax.ejb.Stateless
lub javax.ejb.Stateful
do klasy.
@Stateless
public class BookingService {
public String makeReservation(Item Item, Customer customer) {
...
...
}
}
Bezstanowe komponenty bean muszą mieć zależny zakres, podczas gdy stanowe komponenty bean sesji mogą mieć dowolny zasięg. Domyślnie są to transakcje transakcyjne, ale można użyć adnotacji atrybutu transakcji.
Podczas gdy komponenty EJB i ziarna CDI są bardzo różne pod względem funkcji, pisanie kodu w celu ich integracji jest bardzo podobne, ponieważ ziarna CDI można wstrzyknąć do EJB, a EJB można wstrzyknąć do ziaren CDI. Nie ma potrzeby robienia rozróżnienia przy wstrzykiwaniu jednego do drugiego. Ponownie, różne zakresy są obsługiwane przez CDI przy użyciu proxy. Jedynym wyjątkiem jest to, że CDI nie obsługuje wstrzykiwania zdalnych EJB, ale można to zaimplementować, pisząc dla niego prostą metodę producenta.
javax.inject.Named
Adnotacji, jak również wszelkie kwalifikacje mogą być wykorzystane na EJB, aby dopasować go do punktu wtrysku.
Kiedy używać jakiej fasoli
Skąd wiesz, kiedy użyć której fasoli? Prosty.
Nigdy nie używaj fasoli zarządzanych przez JSF, chyba że pracujesz w kontenerze serwletów i nie chcesz próbować uruchomić CDI w Tomcat (chociaż istnieją na to archetypy Mavena, więc nie ma wymówki).
Ogólnie rzecz biorąc, powinieneś używać komponentów bean CDI, chyba że potrzebujesz zaawansowanych funkcji dostępnych w EJB, takich jak funkcje transakcyjne. Możesz napisać własny przechwytywacz, aby tworzyć transakcje ziaren CDI, ale na razie łatwiej jest używać EJB, dopóki CDI nie otrzyma transakcyjnych ziaren CDI, które są tuż za rogiem. Jeśli utkniesz w kontenerze serwletów i używasz CDI, wtedy albo ręcznie napisane transakcje, albo twój własny przechwytywacz transakcji jest jedyną opcją bez EJB.
Jeśli potrzebujesz użyć @ViewScoped
w CDI, powinieneś
- użyj powierzchni szwów lub modułu MyFaces CODI . po prostu dodaj jeden z nich do swojej ścieżki klas i
@ViewScoped
będzie działać w CDI. MyFaces CODI ma jeszcze solidniejszą obsługę @ViewScoped
- użyj MyFaces CODI
@ViewAccessScoped
, jest to rozszerzenie napisane na CDI przez Apache, po prostu pobierz i użyj @ViewAccessScoped
adnotacji zamiast @ViewScoped
.
- Użyj CDI
@ConversationScoped
i spraw, by działało długo. Więcej informacji znajdziesz tutaj .
- Użyj adnotacji Omnifaces @ViewScoped
Niektóre części okradano stąd .