2. Szew
● Miejsce zszycia kawałków tkaniny, futra itp.
wraz z nićmi, którymi te kawałki zszyto.
● Operacyjne zszycie tkanek miękkich.
● Naturalne połączenie dwu przylegających do
siebie kości spojonych tkanką łączną.
● Połączenie brzegów przedmiotów metalowych
za pomocą nitkowania lub spawania.
6. Stos aplikacji
● Integruje różne frameworki z różnych warstw
JEE
● Widoku (JSF, RichFaces, ICEFaces, Wicket)
● Dostępu do danych (JPA, Hibernate)
● i więcej ...
7. Kontener komponentów
● Integruje komponenty JPA, EJB, POJO oraz
JSF w taki sposób, że zaciera granice
pomiędzy poszczególnymi warstwami i daje
wrażenie korzystania z jednego kontenera
8. Komponenty i kontenery
Kontener Tworzenie komponentu
EJB @Stateful, @Stateless, @MessageDriven, ejb-
jar.xml
JSF faces-config.xml
Spring applicationContext.xml
Kontener servletów web.xml
15. Inversion of Control
● Wzorzec projektowy „rozluźniający” powiązania
pomiędzy komponentami
● Pozwala komponentom na skupienie się na
wykorzystywaniu innych komponentów
(serwisów) niż ich wyszukiwaniu
● Wszyscy go dobrze znają...
16. Inversion of Control
● Zwykle ludzie mówiąc o IoC mają na myśli
dependency injection (DI), jeden z przypadków
użycia IoC
● Jednakże IoC > DI
17. DI jest zbyt statyczne
Problem z klasycznym podejściem do DI jest taki,
że wstrzykiwanie zależności odbywa się tylko raz,
tuż po stworzeniu instancji komponentu.
Komponent jest przywiązany do referencji
obiektów wstrzykniętych mu w czasie tworzenia.
Komponenty powinny być świadome swojego
istnienia w kontekście i powinny brać aktywny
udział w zarządzaniu komponentami.
18. IoC w Seam
● W Seam mamy do czynienia z dependency
bijection
● W Seam zależności są wstrzykiwane
dynamicznie w czasie życia komponentu, a nie
tylko podczas jego tworzenia
● Dependency bijection pozwala na
wstrzykiwanie zależności do komponentu, jak i
umieszczanie komponentów w kontekście
● Bijection = injection + outjection
19. Bijection
● Bijection jest to kombinacja injection i outjection
● Bijection zachodzi w momencie wywołania
metody (a nie tworzenia komponentu)
● Injection w momencie wywołania metody
● Outjection po powrocie metody
20. Disinjection
● Wszystkie pola komponentów do których
zostały wstrzyknięte zależności otrzymują
wartość null.
● Zapobiega wyciekom pamięci
● Rozwiązuje problem serializacji obiektów
21. Bijection interceptor
Komponent wywołujący
metodę
Interceptor
Wstrzykiwanie zależności
w pola oznaczone adnotacją @In
Wywołanie metody
Outjection na polach oznaczonych
adnotacją @Out
Disinjection na polach
oznaczonych adnotacją @In
Powrót z metody
22. Bijection w akcji
1. @Name("authenticator")
2. public class Authenticator {
3. @In
4. private Credentials credentials;
5.
6. @Out(scope = ScopeType.SESSION, required = false)
7. private Long currentUserId;
8.
9. @In(create = true)
10. private UserQuery userQuery;
11.
12. public boolean authenticate() {
13. userQuery.setUsername(credentials.getUsername());
14. User user = userQuery.getSingleResult();
15. if (isPasswordValid(credentials.getPassword(), user)) {
16. currentUserId = user.getId();
17. }
18. }
19.
20. // pozostałe metody
21. }
23. Inne formy wstrzykiwania zależności
● @RequestParameter
● @PersistenceContext
● @DataModelSelection
● @DataModelSelectionIndex
27. Zdarzenia
● Seam posiada wbudowane wsparcie dla
wzorca observer, który w znacznym stopniu
pozwala redukować zależności między
komponentami (budować luźne powiązania)
● Seam pozwala na generowanie zdarzeń z
metod jak i ich obsługę z metod komponentów
● Zdarzenia mogą być generowane na wiele
sposobów, jak i można generować wiele typów
zdarzeń (synchroniczne, asynchroniczne,
czasowe, transakcyjne)
34. Wbudowane zdarzenia
● Inicjalizacja kontenera seamowego
● Przypisanie zmiennej kontekstowej (added,
removed)
● Zdarzenia cyklu życia komponentów (created,
destroyed)
● Zdarzenia związane z autentykacją
● Zdarzenia związane z transakcją
● i wiele innych...
36. Metody fabrukujące w Seam
● Seam posiada wbudowane wsparcie dla
wzorca factory method
● Fabryka ma na celu dostarczenie konkretnych
danych zamiast instancji komponentu
● Metody fabrykujące oznacza się adnotacją
@Factory lub w deskryptorze komponentów
● Metody fabrykujące z założenia mają wypierać
użycie „getterów”
37. Metoda fabrykująca jest wykonywana tylko
raz, kolejne wywołania zwracają utworzoną i
umieszczoną w kontekście wcześniej wartość.
38. Rezultat wywołania fabryki
● Rezultat metody fabrykującej może być
przekazany na trzy sposoby:
● Przez zwrócenie wartości z metody
● Przez outjection (jako, że metoda fabrykująca
znajduje się w komponencie to działa na nim
bijection)
● Przez umieszczenie wartości bezpośrednio w
kontekście
39. Przykład metody fabrykujacej
1. @Name("currentUserFactory")
2. public void CurrentUserHome {
3. @In private EntityManager em;
4.
5. @In private Long currentUserId;
6.
7. @Factory("currentUser")
8. public User getCurrentUser() {
9. return em.find(User.class, currentUserId);
10. }
11. }
40. Przykład metody fabrykujacej
1. @Name("currentUserFactory")
2. public void CurrentUserHome {
3. @In private EntityManager em;
4.
5. @In private Long currentUserId;
6.
7. @Out private User currentUser;
8.
9. @Factory("currentUser")
10. public User getCurrentUser() {
11. currentUser =
12. em.find(User.class, currentUserId);
13. }
14. }
42. Unwrap
● Seam pozwala dostarczać dane do kontekstu
za pomocą metody oznaczonej adnotacją
@Unwrap
● W odróżnieniu od metody fabrykującej taka
metoda jest wywoływana za każdym razem,
kiedy komponent pod konkretną nazwą jest
żądany
43. @Unwrap a @Factory
● Jest prawdziwym komponentem
● Można konfigurować w components.xml
● Można używać adnotacji @Create i @Destroy
● Metoda oznaczona @Unwrap jest wywoływana
zawsze
● Komponent może przechowywać stan i
obserwować zdarzenia
47. Interceptory w Seam
● Seam rozszerza funkcjonalność interceptorów z
EJB
● Przenosi ją ze świata Java EE to świata POJO
● Pozwala w deklaratywny sposób dodawać
logikę AOP
49. Definiowanie interceptora
1. @Interceptor(stateless = true,
2. type = InterceptorType.CLIENT
3. public class StatelessInterceptor {
4.
5. @AroundInvoke
6. public Object methodName(InvocationContext ctx)
7. throws Exception {
8. // interceptor logic...
9. return ctx.proceed();
10. }
11.
12. }
50. Cechy interceptora w Seam
● Interceptor może być stateful-owy lub stateless-
owy
● Interceptory mogą być przypisywane do
komponentów zarówno po stronie serwera jak i
klienta
● Interceptory mogą być przypisywane do klas
deklaratywnie (stereotypes)
52. Przypisywanie interceptorów
● @Interceptors
● W Seamie, w odróżnieniu od EJB, adnotacja
@Interceptors nie jest nakładana na klasy
komponentów, które chcemy interceptować
● Adnotacja ta to meta adnotacja którą nakłada
się na inne adnotacje
53. Przypisywanie interceptorów
1. @Target(TYPE)
2. @Retention(RUNTIME)
3. @Interceptors(CurrentUserAccessInterceptor.class)
4. public @interface VerifyCurrentUserAccess {}
5.
6. @Name("offerAddAction")
7. @VerifyCurrentUserAccess
8. public class OfferAddAction { }
59. Konwersacja w Seam
● Pozwala przechowywać stan komponentów
pomiędzy kolejnymi żądaniami (nawet w
przypadku występowania przekierowań)
● Jest bardziej ziarnista niż kontekst sesji
● W deklaratywny sposób można kontrolować
zakresy konwersacji (oraz jej propagacje)
● Na czas konwersacji Seam rozpina transakcje
(utrzymywana jest sesja połączenia z bazą
danych)
60. Konwersacja w Seam została pomyślana jako
kontekst, który przechowuje stan
komponentów w ramach konkretnego
przypadku użycia.
61. A czemu nie w sesji?
● Sesja jest zbyt długa i przechowywanie danych
w tym kontekście może prowadzić do wycieków
pamięci
● Sesja jest dzielona pomiędzy karty przeglądarki
● Sesja nie posiada żadnych mechanizmów
obronnych przed współbieżnym dostępem do
danych
● Błędy występujące przez nieprawidłowe
wykorzystywanie kontekstu sesji mogą być
trudne do reprodukcji w środowisku testowym
64. Seam zarządza konwersacją
● Każda konwersacja posiada określony czas
trwania (timeout)
● Każda konwersacja toczy się w izolacji (nie
trzeba się przejmować synchronizacją)
65. Wymagania konwersacji
● Komponenty muszą implementować interfejs
java.io.Serializable
● Czas trwania sesji musi być dłuższy niż czas
trwania konwersacji
68. Przejścia stanów konwersacji
brak konwersacji kontynuacja konwersacji
begin
Temporary Long-running
end
koniec żądania sesja lub konwersacja
wygasła
Zniszczona Zniszczona
69. Stany długiej konwersacji
Long-running
resumed
concurrent conversation resumed
begin
resumed
Foreground Background
end
session timeout conversation or
session timeout
Zniszczona
81. Problemy z JSF
● Skrócony cykl JSF
● Służy jako dostawca strony
● Zakłada, że nie potrzeba wykonywania żadnej logiki
przed wyrenderowaniem strony
● Zakłada, że użytkownik posiada uprawnienia do
żądanego zasobu
● Zorientowanie na żądania typu POST
● Mało rozwinięte reguły nawigacji
● Brak możliwości wykorzystania EL w regułach
83. Do czego służy deskryptor strony
● Definiowania reguł nawigacji
● Generowania komunikatów (FacesMessages)
● Mapowania parametrów URL
● Dodawania parametrów URL (dla
przekierowań)
● Uruchamiania akcji zanim widok zostanie
wyrenderowany
84. Do czego służy deskryptor strony
cd...
● Sprawdzania reguł bezpieczeństwa
● Kontrolowania zakresów konwersacji
● Kontrolowania zakresów page flow
● Kontrolowania zakresów procesów
biznesowych i zadań
● Wywoływanie eventów
● Obsługa wyjątków
86. Inteligentna nawigacja w Seam
● Pozwala użyć dowolnej wartości (dostępnej za
pomocą EL) do definiowania przekierowań
● Reguły nawigacji są warunkowe
● Definiuje jak powinna być propagowana
konwersacja, czy proces biznesowy
● Pozwala dodawać komunikaty JSF przed
wyrenderowaniem strony bądź przekierowaniem
● Pozwala dodawać parametry URL
● Pozwala wywoływać eventy
92. Mapowanie parametrów strony
● Seam pozwala na ustawianie wartości pól
komponentu w skróconym cyklu JSF (JSF
pozwala tylko w postbacku)
● Parametrem strony może być wartość z
formularza (POST) jak i parametr URL (GET)
● Parametry mogą być przypisane do dowolnych
pól każdego komponentu Seam (osiągalnego
za pomocą EL)
94. Właściwości parametrów
● Do każdego parametru można zdefiniować
JSF-owe walidatory i konwertery takie jak
definiuje się dla normalnego postbackowego
cyklu
● Można zdefiniować, że parametr jest
wymagany bądź opcjonalny
● Parametrów nie trzeba przypisywać do
konkretnych pól komponentu, takie parametry
mogą po prostu przechowywać dane między
kolejnymi żądaniami
95. URL rewrite
● Seam pozwala na przepisywanie adresów URL
zgodnie z szablonem zdefiniowanym w
deskryptorze strony
● Seam przepisuje URL-e zarówno żądań
przychodzących jak i odpowiedzi aplikacji
99. Akcje strony
● Seam pozwala na wykonywanie akcji dla danej
strony (view-id) tuż przed jej wyrenderowaniem
(nawet w skróconym przebiegu JSF)
● Są to standardowe akcje dla których można
definiować reguły nawigacji (wywoływane
jednak przed szóstą fazą JSF a nie w piątej!)
● Akcje te mogą służyć do zainicjalizowania
widoku – załadowania danych potrzebnych do
wyrenderowania strony
● Pozwala to na implementacje RESTful-owych URL-i
101. Czego Seam nie poprawia
● Komunikatów JSF
● Walidacja i konwersja dotyczą tylko
pojedynczych wartości, nie jest łatwo
zaimplementować tych operacji na zależnych
polach (i trzeba przenosić ten proces do piątej
fazy)
● Wstrzykiwanie zależności do walidatorów i
konwerterów (można je pobierać za pomocą
metod statycznych)
102. Czego nie omówiono w prezentacji?
● Deskryptor komponentów components.xml
● Seam-gen
● WebBeans (JSR-299)
● Workspace i pageflow w kontekście konwersacji
● Wsparcia Seam dla warstwy widoku
● Komponenty seamowe
● Wsparcie dla AJAX
● Testowanie integracyjne
● Symulacja cyklu JSF
● Kontekstu business process