Oprócz programowego podejścia do uruchamiania i planowania wykonania zadań Spring w ramach konfiguracji xml'owej udostępnia specjalną przestrzeń wspierającą współbieżność: xmlns:task="http://www.springframework.org/schema/task" dostępnej pod adresem: xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd".
Dzięki konfiguracji można zdefiniować executor'a, scheduler'a czy opisać zadania, które mają zostać zrealizowane z wykorzystaniem konkretnego mechanizmu. Przyjrzyjmy się zatem konkretnym przykładom.
Definiowanie executor'a
Rzućmy najpierw okiem na przykład:
<task:executor id="executor" pool-size="1-10" queue-capacity="200" keep-alive="60" rejection-policy="DISCARD_OLDEST"/>
Powyższa definicja jest tak naprawdę odpowiednikiem definicji springowego bean'a będącego ThreadPoolTaskEecutor'em o identyfikatorze executor (identyfikator ten będzie prefixem dla nazw wątków przypisanych do tego executor'a), mającego określoną core'ową (1) i maksymalną (10) liczbę wątków, pojemność kolejki - 200, a czas życia wątku bez przydzielonego zadania 60 sekund, dodatkowo w przypadku przekroczenia wielkości kolejki i sytuacji w której wszystkie wątki pracują obowiązuje polityka wycofywania najstarszego zadania.
Definiowanie scheduler'a
Przykład:
Tak jak w przypadku executor'a, który jest bean'em ThreadPoolTaskExecutor, tak w tym wypadku powyższa definicja jest równoważna definicji bean'a ThreadPoolTaskScheduler o identyfikatorze "schedulerId" i przypisanej liczbie wątków równej 10.
Definiowanie zadań do wykonania
Skoro w łatwy sposób w ramach xml'owej konfiguracji można utworzyć mechanizmy współbieżności czy da się również zdefiniować w łatwy sposób to co ma być wykonane? Okazuje się, że tak: wystarczy skorzystać z scheduled-tasks.
Załóżmy, że mamy zdefiniowany scheduler - tak jak przedstawiono powyżej oraz dodatkowo bean'a springowego o identyfikatorze: businessId, który udostępnia jedną, bezparametrową metodę processWork. Chcielibyśmy, aby ta metoda odpalana była np. co 5 sekund od poprzedniego uruchomienia. Dzięki xml'owej konfiguracji powyższe wymagania można zrealizować za pomocą poniższego kodu:
Element task:scheduled pozwala wskazać na bean'a (atrybut ref) oraz na metodę tego bean'a (atrybut method), która ma być cyklicznie uruchamiana. Dodatkowo możliwe jest określenie cyklu uruchamiania zadania (za pomocą fixed-rate, fixed-delay, wyrażenia cron lub własnej implementacji interfejsu Trigger'a.)
W ramach pojedynczej definicji scheduled-tasks można określić wiele zadań wykonywanych przez ten sam scheduler.
Adnotacje i współbieżność
Nie da się obecnie nie zauważyć, że coraz częściej zamiast konfiguracji xml'owej preferowane są adnotacje. W tym zakresie Spring wychodzi naprzeciw oczekiwaniom i dostarcza dwie adnotacje, pierwsza pozwala oznaczyć metodę jako wykonywalną asynchronicznie: Async. Natomiast druga - Scheduled, oznacza, że dana metoda ma być wykonywana cyklicznie.
Definiowanie scheduler'a
Przykład:
<task:scheduler id="schedulerId" pool-size="10" />
Definiowanie zadań do wykonania
Skoro w łatwy sposób w ramach xml'owej konfiguracji można utworzyć mechanizmy współbieżności czy da się również zdefiniować w łatwy sposób to co ma być wykonane? Okazuje się, że tak: wystarczy skorzystać z scheduled-tasks.
Załóżmy, że mamy zdefiniowany scheduler - tak jak przedstawiono powyżej oraz dodatkowo bean'a springowego o identyfikatorze: businessId, który udostępnia jedną, bezparametrową metodę processWork. Chcielibyśmy, aby ta metoda odpalana była np. co 5 sekund od poprzedniego uruchomienia. Dzięki xml'owej konfiguracji powyższe wymagania można zrealizować za pomocą poniższego kodu:
<task:scheduled-tasks scheduler="schedulerId">
<task:scheduled ref="businessId" method="processWork" fixed-rate="5000"/>
</task:scheduled-tasks>
W ramach pojedynczej definicji scheduled-tasks można określić wiele zadań wykonywanych przez ten sam scheduler.
Adnotacje i współbieżność
Nie da się obecnie nie zauważyć, że coraz częściej zamiast konfiguracji xml'owej preferowane są adnotacje. W tym zakresie Spring wychodzi naprzeciw oczekiwaniom i dostarcza dwie adnotacje, pierwsza pozwala oznaczyć metodę jako wykonywalną asynchronicznie: Async. Natomiast druga - Scheduled, oznacza, że dana metoda ma być wykonywana cyklicznie.
- Scheduled - pozwala za pomocą 3 wykluczających się wzajemnie parametrów określić cykliczność uruchamiania danej metody (cron, fixedDelay lub fixedRate). Metoda, której adnotacja jest przypisywana musi być metodą bezparametrową zwracającą void'a.
- Async - metoda, której zostanie przypisana adnotacja Async może przyjmować wiele parametrów natomiast nie może zwracać niczego poza void'em lub Future'em. W momencie wywołania rejestrowane jest zadanie do wykonania, natomiast sterowanie natychmiast zwracane jest do wywołującego wątku. Adnotacji tej nie można łączyć z adnotacjami zarządzającymi cyklem życia bean'a springowego.
Poniżej przykłady:
1: @Scheduled(cron="* * * * * *")
2: public void scheduleWork() {
3: // some work...
4: }
Metoda scheduleWork() będzie wywoływana co 1 sekundę
Wywołania powyższej metody będą wykonywane asynchronicznie. Metoda przyjmuje jeden parametr i w odpowiedzi po przeliczeniu danych zwraca wartość całkowitą, która dostępna będzie w wątku wywołującym po przetworzeniu zlecenia przez wątek z puli realizujących zadania asynchroniczne.
1: @Async
2: public Future<Integer> processWork(int i) {
3: // some work...
4: return new AsyncResult<Integer>(10);
5: }
Z dobrodziejstwa adnotacji można skorzystać po odpowiednim skonfigurowaniu kontenera. W konfiguracji XML'owej należy dodać:
W ten sposób definiuje się, że wszelkie wywołania metod z adnotacjami Async będą wykonywana przez executora: executorBean, natomiast wszystkie cykliczne zadania (metody z adnotacjami Scheduled) będą realizowane przez scheduler: schedulerBean.
Myślę, że tym akcentem można zamknąć temat współbieżności w Springu i w Javie. Kolejny temat, który zamierzam opisać w ramach przygotowań do zdobycia certyfikatu to wywołania zdalne.
<task:annotation-driven executor="executorBean" scheduler="schedulerBean"/>
Myślę, że tym akcentem można zamknąć temat współbieżności w Springu i w Javie. Kolejny temat, który zamierzam opisać w ramach przygotowań do zdobycia certyfikatu to wywołania zdalne.
Brak komentarzy:
Prześlij komentarz