13 stycznia 2007

Chapter 8 - Enterprise Bean Context and Environment i Chapter 9 - Compatibility and Migration przeczytane!

I kolejne rozdziały specyfikacji EJB3 Simplified przeczytane! Czyta się je wyjątkowo sprawnie - odpowiedni styl pisania o wszystkich uproszczeniach w EJB3 korzystnie wpływa na jej lekturę. Tym razem kolejne dwa rozdziały poszły pod młotek - Chapter 8 Enterprise Bean Context and Environment oraz Chapter 9 Compatibility and Migration. W zasadzie wszystko już było w poprzednich rozdziałach - pojawiło się trochę detali (sposób na odsianie kilku delikwentów na egzaminie SCBCD).

Chapter 8 Enterprise Bean Context and Environment

Komponent EJB posiada dostęp do prywatnego kontekstu wykonania - stanu środowiska w danej chwili.

Pierwszy raz pojawia się DI poprzez udekorowanie metody modyfikującej właściwość komponentu (ang. setter),

@EJB
public void setInterfejsBiznesowyXYZ(InterfejsBiznesowyXYZ interfejsBiznesowyXYZBean) {
this.interfejsBiznesowyXYZBean = interfejsBiznesowyXYZBean;
}

która jest alternatywą dla DI dla bezpośredniego dostępu do pola instancji.

@EJB
private InterfejsBiznesowyXYZ interfejsBiznesowyXYZBean;

Korzystanie z DI poprzez metodę modyfikującą znacząco poprawia możliwość testowania komponentu poza specjalizowanym środowiskiem DI. Temat poruszony był na ostatnim III spotkaniu Warszawa JUG, gdzie zapytano o wychwalaną przeze mnie prostotę testowania komponentów EJB. Skorzystanie z metody modyfikującej rozwiązuje problem, ponieważ wystarczy przed testowaniem zainicjować komponent, co w przypadku prywatnego pola instancji nie jest zadaniem trywialnym. W zasadzie skłaniam się ku stwierdzeniu, że dekorowanie pól instancji wpływa negatywnie na testy i na chwilę obecną nie jest przeze mnie rekomendowane - stosujemy wyłącznie dekorowanie metod nie pól.

Wracając do rozdziału, do interfejsu javax.ejb.EJBContext dodano metodę lookup, która może posłużyć jako sposób dowiązania do zasobów zewnętrznych, bądź ostatecznie można korzystać z JNDI.

Komponent deklaruje zależności od zasobów zewnętrznych poprzez annotacje (w tym kontekście nazywane annotacjami zależności - ang. dependency annotation). Annotacja służy do wskazania miejsca wstrzelenia zależności, typ zależności, nazwę, pod którą kontener może odszukać zależność w kontekście wykonania i inne cechy charakterystyczne dla zależnego zasobu.

Podano dwa rodzaje annotacji @EJB oraz @Resource. Brak jakichkolwiek argumentów dla annotacji instruuje serwer, że dalsze informacje będą pobrane z kontekstu z jakim są związane, tj. klasy, zmiennej klasy bądź metody.

Dekorowaniu podlegają klasa komponentu, zmienne instancji lub metody.

Dla przypomnienia: DI zachodzi po skonstruowaniu instancji komponentu, przypisaniu jej kontekstu - EJBContext, a przed wywołaniem pierwszej metody biznesowej.

Annotacja @EJB może definiować następujące informacje o wyszukiwanym komponencie:
  • beanInterface - dowolny interfejs komponentu - lokalny/zdalny interfejs biznesowy (dla zgodności z EJB 2.1 również lokalny/zdalny interfejs domowy)
  • beanName - równoważne ejb-name komponentu zależnego
  • mappedName - zgodnie z JavaDoc to specyficzna dla produktu nazwa komponentu EJB - nic mi to nie mówi, niestety (i tak nie jest to przenośne)
  • name - nazwa pod jaką widnieje komponent zależny w prywatnym kontekście wykonania komponentu (java:comp/env)
Annotacja @Resource jest znacznie bogatsza w możliwość wyrażenia danych o zależnym zasobie:
  • authenticationType - typ uwierzytelnienia - APPLICATION, CONTAINER (domyślna wartość)
  • description - opis
  • mappedName - podobnie jak w @EJB - nieprzenośnie, więc nie ma się co tym przejmować
  • name - nazwa pod jaką widnieje zasób w prywatnym kontekście wykonania komponentu (java:comp/env)
  • shareable - false/true (domyślna wartość) - czy jest współdzielona między komponentami
  • type - typ zasobu
, np:

@Resource(name="myDB", description="Baza danych pracowników", authenticationType=APPLICATION)
DataSource customerDB;

@EJB(name="mojaNazwaKomponentu", beanInterface=pl.jaceklaskowski.mojaapp.InterfejsBiznesowyWersja2)
InterfejsBiznesowy interfejsBiznesowyBean;

@EJB(name="komponentXYZ")
public void setCustomerManager(CustomerManager customerManager) {
this.customerManager = customerManager;
}

Nazwa i typ zasobu wyznaczane są poprzez nazwę i typ zmiennej bądź metody, z którą związana jest annotacja.

Wszystko, co dostępne w JNDI - jest do wstrzelenia poprzez annotację. Wszystkie zależne zasoby muszą być dostępne w prywatnym kontekście wykonania (java:comp/env).

Równoważnie, można skorzystać z EJBContext.lookup(String name), gdzie name jest dokładnie nazwą podawaną w @EJB lub @Resource dla argumentu name (przy jego braku znaczenie ma nazwa zmiennej bądź metody modyfikującej, do której się ona odnosi).

Chapter 9 Compatibility and Migration

Pierwsza ważna informacja dla osób aktualnie zaangażowanych w projekty oparte o EJB 2.1, a pracujące w środowisku wspierającym EJB 3.0 - Wasza aplikacja musi pracować bez żadnych zmian związanych z EJB 3.0 (chyba, że wyspecyfikowano jakiekolwiek w RELEASE NOTES, czy podobnie, ale wtedy trudno będzie uzyskać takiemu serwerowi miano zgodności z EJB 3.0).

Nie opisując szczegółów rozdziału nie zauważyłem żadnych obostrzeń w tworzeniu aplikacji Java EE 5 jednocześnie z elementami EJB 2.1 i EJB 3.0. Klienci aplikacyjni również nie są zobowiązani do migracji do nowszej wersji specyfikacji, jeśli ich komponenty EJB korzystają z niej (przypominam, że interakcja między światem zewnętrznym a komponentami zawsze odbywa się poprzez obiekty pośrednie - ang. proxy objects/beans).