Spring Batch Scheduler

Nel post Primi Passi con Spring Batch abbiamo descritto un semplice esempio di job realizzato con Spring Batch. Nell’introduzione abbiamo anche detto che per la schedulazione dei job è necessario integrare un tool che si occupa dell’avvio temporizzato dei batch.

Nel post vediamo due tool di schedulazione: TaskScheduler di Spring e il più noto Quartz. Per farlo ci riferiremo al progetto descritto nel post sopra indicato, in cui è configurato un in memory database come repository, ed un semplice job di lettura e stampa a video.

TaskScheduler

TaskExecutor e TaskScheduler sono interfacce introdotte in Spring 3.0 per la schedulazione di batch. Seguono il modello architetturale degli executor presenti già nel JDK e descritti nel post Programmazione concorrente in java (parte 2). Essendo parte del core non è necessario introdurre altre dipendenze nel progetto.

La configurazione, come al solito, può avvenire tramite annotation o per mezzo dell’XML di contesto. Per omogeneità con il progetto utilizzeremo la seconda modalità. Introduciamo quindi bell’XML context.xml il namespace e lo schema location:

Quindi configuriamo lo scheduler nell’XML utilizzando un bean helloWorldLauncher che definiremo nel seguito e che farà quello che nel progetto originale faceva il main().

Attraverso il tag <task:scheduled> possiamo configurare, oltre al bean ed al metodo metodo da eseguire, le proprietà:

  • fixed-delay: indica l’intervallo (in millisecondi) tra una esecuzione e la successiva;
  • initial-delay: indica il ritardo (in millisecondi) per la prima esecuzione del task;
  • fixed-rate: indica un intervallo (in millisecondi) tra due esecuzioni successive;
  • cron: consente di indicare una espressione cron.

La classe HelloWorldLauncher si occupa dell’avvio vero e proprio del batch. Per farlo riceve dall’IoC container il Job e il JobLauncher.

Infine definiamo il bean nel context.xml:
In questo caso il main() si limiterà a creare il contesto Spring:

Se proviamo ad avviare l’applicazione così com’è, alla secondo avvio del job, e per tutte le esecuzioni successive, otterremo l’eccezione:

A job instance already exists and is complete for parameters={}.  If you want to run this job again, change the parameters.

Quello che accade è che il JobLauncher di Spring si accorge che nel repository esiste già un job eseguito e completato sui parametri indicati, che nel nostro caso non sono valorizzati. Per ovviare al problema, e in considerazione del fatto che il nostro batch non ha parametri di esecuzione, è sufficiente costruire un parametro a partire dall’ora attuale, nel modo seguente:

Quartz Scheduler

Il framework Quartz è una libreria open source le la schedulazione dei job, che può essere integrata con una qualsiasi applicazione java. Per integrarlo con Spring introduciomone la dipendenza nel pom.xm:

Prima di procedere introduciamo il concetto di JobRegistry. Si tratta di un componente di Spring che semplicemente tiene traccia di tutti i job definiti nel contesto. La sola implementazione presente nel framework realizza tale scopo attraverso una semplice mappa tra il nome del job e la sua istanza. Per poter registrare i job nel registro deve essere definito un post processor che li inserisce al momento della sua definizione nel contesto. Introduciamo quindi nel context.xml il seguente codice XML:

Per l’integrazione di Quartz in Spring il framework mette a disposizione l’interfaccia QuartzJobBean. Implementiamo quindi tale interfaccia per generare il bean che si occuperà di lanciare il job. Come nel caso precedente abbiamo bisogno di iniettare il JobLauncher mentre per il recupero del job utilizziamo il repository appena definito. La classe HelloWorldJobLauncherDetails avrà il seguente aspetto:

Infine configuriamo Quartz ed i dettagli del job launcher nel context.xml:

Codice Sorgente

Il codice sorgente è scaricabile qui spring-batch.

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

As you found this post useful...

Follow us on social media!