07 stycznia 2007

Chapter 5 - Stateful Session Beans oraz lektura książki Enterprise JavaBeans 3.0 wyd. 5 z O'Reilly

Pisałem wczoraj o konieczności zakasania rękawów i tak je zakasałem, że miałem je po same barki i...udało mi się znaleźć trochę czasu na lekturę 2 rozdziałów z 5. wydania książki Enterprise JavaBeans 3.0 z O'Reilly autorstwa Bill Burke i Richard Monson-Haefel. Pierwszego znamy z grupy tworzącej serwer aplikacyjny JBoss AS, a drugi to bodajże pierwszy z autorów, któremu udało się opisać EJB w niezwykle przystępny sposób (dla dociekliwych dodam, że Richard był założycielem projektu Apache OpenEJB - kontenera EJB - jeszcze w czasach finansowania projektu przez Intalio i później na SourceForge).

Muszę przyznać, że Bill wie o czym pisze, co zresztą zostało zauważone we wstępie napisanym przez koordynatora grupy standaryzującej EJB3 - Linda DeMichiel. Pierwsze dwa rozdziały zdają się wskazywać, że lektura książki upraszcza zrozumienie specyfikacji EJB3 i jakkolwiek do końca daleko, to skłaniam się ku ocenie, że książkę warto mieć na swojej półce.

Z wielkim zainteresowaniem wysłuchałbym opinii osób, którzy ją przeczytali i zechcieliby podzielić się swoimi wrażeniami, a może nawet i zarekomendowali dalsze kroki czytelnicze i praktyczne?!?!

Mimo zainteresowania książką, dla uatrakcyjnienia weekendu kontynuuję czytanie specyfikacji EJB3 Simplified (w końcu na niej zamierzam oprzeć egzamin na javaBLACKbelt). Tym razem przyszła kolej na rozdział 5: Stateful Session Beans. Zobaczmy co można, a czego nie można w SFSB (ang. stateful session bean)?
  • Business interfejs to zwykły interfejs w Javie, zero EJBObject czy EJBLocalObject
  • Koniec z interfejsem domowym do pobrania referencji do SFSB - DI albo JNDI wystarczy
  • Annotacja @Stateful lub definicja w deskryptorze instalacji. Nie ma potrzeby implementować javax.ejb.SessionBean lub java.io.Serializable. Ale...można implementować SessionBean (wsparcie dla kodu z poprzednich wersji EJB, gdzie była taka konieczność) oraz mimo, że Serializable jest interfejsem-znacznikiem, który wskazuje na możliwość zapisu stanu obiektu w Javie, to kontener EJB musi obsłużyć pasywację i aktywację stanowych komponentów sesyjnych pomimo braku jego użycia (gdzieś czytałem, że jest to dobra praktyka korzystanie z interfejsu - zresztą, to nie boli ;-)).
  • Pojawia się interfejs SessionSynchronization, jednak ze wskazaniem, że opis znajduje się w części specyfikacji EJB Core.
  • Metody zwrotne związane z cyklem życia komponentu - wspierane zdarzenia to:
    • tworzenie
    • niszczenie (usuwanie)
    • aktywacja
    • pasywacja
    (dla przypomnienia - w bezstanowym komponencie EJB mieliśmy wyłącznie dwa, bez aktywacji i pasywacji).
    Zdefiniowano następujące annotacje do wskazania metod zwrotnych w komponencie bądź w samej klasie interceptora:
    • @PostConstruct
    • @PreDestroy
    • @PostActivate
    • @PrePassivate
    Dodano uwagę o braku przypadków użycia dla wprowadzenia ich odpowiedników (dla Post Pre i na odwrót).
    Podobnie jak to ma miejsce dla SLSB, @PostConstruct wywoływane jest po stworzeniu nowej instancji komponentu, po wstrzeleniu zależności, ale przed wywołaniem pierwszej metody biznesowej. @PreDestroy wywoływane jest po zakończeniu wykonania metod oznaczonych @Remove (ciekawostką jest opisanie działania annotacji @PreDestroy w rozdziale o SLSB i SFSB - w poprzednim napisano, że metoda @PreDestroy wywoływana jest przy usuwaniu instancji komponentu SLSB, a teraz napisano dokładniej, kiedy takie zdarzenie jest generowane - po poprawnym wywołaniu metod @Remove).
    @PostConstruct i @PreDestroy wywoływane są w nieokreślonym kontekście transakcji i bezpieczeństwa.
    Wykonanie metod @PrePassivate i @PostActivate opisano jako identyczne z wykonaniem metod ejbActivate i ejbPassivate w EJB 2.1 oraz wskazano na dokładniejsze wyjaśnienie w specyfikacji EJB Core.
  • Wstrzeliwanie zależności odbywa się przed wykonaniem metod biznesowych i metod zwrotnych.
  • SFSB wspiera interceptory @AroundInvoke określone na klasie komponentu bądź w klasie interceptora. Dotyczą wyłącznie wywołań metod biznesowych.
  • Wyjaśniono zależność między metodami interfejsu SessionSynchronization - afterBegin i beforeCompletion - a interceptorami @AroundInvoke. Kolejność wywoływania metod to:
    1. SessionSynchronization.afterBegin
    2. @AroundInoke
    3. SessionSynchronization.beforeCompletion
  • W rozdziale znajduje się przykład SFSB z wstrzeleniem SessionContext, który za pomocą metody zwrotnej @PostConstruct i @PostActivate oraz @PreDestroy i @PrePassivate zarządza gniazdem (ang. socket). Komponent zawiera metodę @Remove oraz @AroundInvoke.
  • Z punktu widzenia klienta dostęp do SFSB odbywa się poprzez DI albo JNDI. Każdorazowe pozyskanie komponentu za pomocą JNDI wiąże się z pobraniem nowej instancji komponentu. Nie napisano (tj. nie znalazłem), co będzie w sytuacji, kiedy pozyskanie SFSB odbywa się przy pomocy DI (prawdopodobnie, jak możnaby przypuszczać, mamy wtedy utrzymywanie tej samej instancji).
    Kiedy SFSB jest wstrzelone (DI) do kontekstu klienta lub pozyskane przez JNDI, stworzona instancja komponentu jest zainicjowana z punktu widzenia JVM, ale niekoniecznie z punktu widzenia biznesowego, aż do wywołania metody "create", gdzie cały stan komponentu zostanie utworzony (do sprawdzenia, o co tak na prawdę chodzi - nie pamiętam, aby była mowa o jakiejkolwiek metodzie create. Może chodzi o @PostConstruct?).
    Ach, następnie opisano scenariusz, gdzie komponent dostarcza metodę biznesową do inicjalizacji biznesowej komponentu (ala create).
  • Annotacja @Remove służy do oznaczenia metody biznesowej SFSB, której wykonanie wskaże kontenerowi moment usunięcia instancji (jak doczytałem w Java EE API - annotacja dostarcza parametr retainIfException, który jeśli przyjmuje wartości true, określa, że SFSB nie będzie usunięty przez kontener, gdy metoda zakończy się wyjątkiem).
    Dla zobrazowania tematu zaprezentowano przykład, komponentu modelującego koszyk (ShoppingCartBean) z metodą startToShop (inicjującą komponent biznesowo), addToCart (typowa metoda biznesowa) oraz finishShopping (oznaczona annotacją @Remove, której pomyślne bądź w tym przypadku niepomyślne zakończenie wskazuje kontenerowi moment dozwolonego usunięcia komponentu).
Najwyższa pora zabrać się za dokończenie prezentacji na wtorkowe spotkanie.