2009-12-21 18 views
13

Chcę uruchomić proces w tle równolegle z moją aplikacją webową spring-mvc. Potrzebuję sposobu, aby zacząć automatycznie przy ładowaniu kontekstowym. Proces w tle jest klasą, która implementuje Runnable. Czy spring-mvc ma w tym coś do zaoferowania?Jak stworzyć proces w tle na wiosnę?

Odpowiedz

11

Wiosna ma kompleksowe ramy wykonywania zadań. Zobacz relevant part of the docs.

Proponuję posiadanie Spring bean w twoim kontekście, który po zainicjowaniu przesyła twoje tło Runnable do fasoli SimpleAsyncTaskExecutor. To najprostsze podejście, które możesz uczynić bardziej złożonym i zdolnym, jak uważasz za stosowne.

7

Chciałbym przeczytać dokumentację planowania zadań powiązaną ze skaffmanem, ale jest też prostsza metoda, jeśli naprawdę chcesz tylko uruchomić wątek w tle podczas inicjalizacji kontekstu.

<bean id="myRunnableThingy"> 
    ... 
</bean> 

<bean id="thingyThread" class="java.lang.Thread" init-method="start"> 
    <constructor-arg ref="myRunnableThingy"/> 
</bean> 
+1

Czy to działa dobrze z zamykaniem kontekstu i tak dalej? –

+1

To dobre pytanie, zamknięcie może być trudne. Idealnie chciałbyś zrobić 'interrupt()', po którym następuje 'join()'. Niestety, nie wierzę, że możesz mieć dwie "metody niszczenia", więc najlepiej, jak to możliwe, jest 'destroy-method =" interrupt "'. Dla prawidłowego zachowania podczas zamykania zaleca się wdrożenie [Lifecycle] (http://docs.spring.io/spring/docs/4.1.0.BUILD-SNAPSHOT/javadoc-api/org/springframework/context/Lifecycle.html) lub [Cykl SmartLifecycle] (http://docs.spring.io/spring/docs/4.1.0.BUILD-SNAPSHOT/javadoc-api/org/springframework/context/SmartLifecycle.html) – washley

+0

Implementacja interfejsu sprężynowego nie jest dostępna oczywiście duch mojej oryginalnej odpowiedzi. – washley

2

Jako kolejna opcja, można teraz korzystać z funkcji planowania Spring. Z wersją Spring 3 lub wyższą ma ona adnotację typu cron, która pozwala zaplanować uruchamianie zadań za pomocą prostej adnotacji metody. Jest również przyjazny w przypadku autowirowania.

W tym przykładzie zadania są planowane co 2 minuty przy początkowym okresie oczekiwania (przy uruchomieniu) wynoszącym 30 sekund. Następne zadanie uruchomi się 2 minuty po zakończeniu metody! Jeśli chcesz, aby był uruchamiany dokładnie co 2 minuty, użyj zamiast niego fixedInterval.

@Service 
public class Cron { 
private static Logger log = LoggerFactory.getLogger(Cron.class); 

@Autowired 
private PageService pageService; 

@Scheduled(initialDelay = 30000, fixedDelay=120000) // 2 minutes 
public void cacheRefresh() { 
    log.info("Running cache invalidation task"); 
    try { 

     pageService.evict(); 
    } catch (Exception e) { 
     log.error("cacheRefresh failed: " + e.getMessage()); 
    } 
} 

} 

Należy również dodać @EnableAsync @EnableScheduling do klasy aplikacji, aby włączyć tę funkcję.