Problema:
Vogliamo che il nostro sistema esegua determinati task in determinati momenti e che tutto sia automatizzato.
La soluzione esite già ed è il framework Quartz:una libreria per lo scheduling dei Job scritta in java.
Vediamo quali sono i principali oggetti che ci permettono di utilizzarne le funzionalità.
Lo Scheduler , che è responsabile dell'esecuzione dei Job che gli sono stati registrati.
I Job, ovvero i nostri task da automatizzare.
I Trigger, che triggerano l'esecuzione di un Job.
Naturalmente questi oggetti agiscono insieme per creare uno scheduling che funzioni.
I passi base sono questi.
1)Creiamo il nostro Job. Per farlo basta crare una classe che implementi l'interfaccia org.quartz.Job
, che ha il seguente metodo da implementare:
public void execute(JobExecutionContext context) throws JobExecutionException;
nel metodo execute metteremo la nostra business logic.
public class MyJob implements Job {
public MyJob() {
}
public void execute(JobExecutionContext context) throws JobExecutionException {
//Qui ci sarà la nostra logica di business
}
}
2)Creiamo il Trigger, usando uno di quelli messi a disposizione da Quartz o implementandone uno nostro estendendo la classe org.quartz.Trigger
.
In base al Trigger che abbiamo scelto, avremo modi diversi di definire quando il trigger deve scatenare l'esecuzione del Job.
Ad esempio per instanziare un SimpleTrigger scriveremo:
...
SimpleTrigger trigger1 = new SimpleTrigger("trigger1", "group1", "job1", "group1",
new Date(<valore>), null, 4, 10000);
Con questo Trigger diciamo allo Scheduler che a partire dalla data passata come 5° argomento, scateneremo il Job associato (vedremo come si fa) 4 volte ad intervalli di 10 secondi.
Ad uno stesso Job possiamo associare trigger diversi, mentre un trigger può essere associato ad un solo Job.
3)Creiamo lo Schduler
..
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler sched = sf.getScheduler();
4)Creiamo un oggetto JobDetail, nel quale specifichiamo il Job (la nostra classe MyJob)
...
JobDetail job1 = new JobDetail("job1", "group1", MyJob.class);
Attenzione, se vogliamo eseguire istanze multiple dello stesso job, dobbiamo creare un JobDetail per ogni istanza che vogliamo eseguire.
5)Registriamo allo scheduler il Job, associandogli il Trigger che vogliamo sia responsabile di scatenare l'esecuzione del Job stesso.
sched.scheduleJob(job1, trigger1);
Job e Trigger possono essere aggiunti e rimossi dallo scheduler in qualiasi momento, eccetto dopo la chiamata di
sched.shutdown();
6)Chiamiamo infine
sched.start();
Lo Scheduling avverrà nel seguente modo.
Al momento opportuno, il Trigger scatenerà l'esecuzione del Job, che lo Scheduler eseguirà instanziano la classe opportuna e invocando il metodo execute()
.
Quello appena descritto è il metodo più semplice per schedulare dei Job e si adatta alle piccole applicazioni, in cui modificare i sorgenti e ricompilare non rappresenta un costo eccessivo.
Ma in progetti complessi questo metodo potrebbe rivelarsi problematico. Per ovviare questo problema Quartz offre la possibilità di definire le caratteristiche della nostra applicazione
tramite file di configurazione.
Il file quartz.properties
, che definisce proprietà e comportamenti della nostra applicazione.
Un file xml nel quale è possibile dichiarare i Job e i Trigger da registrare allo Scheduler.
Nel nostro esempio una volta che lo scheduler viene stoppato, tutti le informazioni riguardo a quale Job è stato eseguito e quale no viene persa.
Quartz mette a disposizione i JobStores, per fornire un meccanismo di memorizazzione per Job, Trigger Calendar e informazioni sullo Scheduler.
Sono di due tipi
- Memory (nonpersistent) storage
- Persistent storage
Di default viene utilizzato il primo tipo, tramite la classe org.quartz.simpl.RAMJobStore
. Se l'applicazione però termina inaspettatamente tutti le informazioni per lo scheduling andranno perse.
Se vogliamo che le informazioni siano persistenti, Quartz mette a disposizione un meccanismo per memorizzare le informazioni su un database, tramite l'interfaccia JobStoreSupport
.
La scelta di quale meccanismo utilizzare è naturalmente legata al tipo di requisiti che la nostra applicazione deve soddisfare.
La documentazione completa su Quartz è consultabile qui.