Ho un requisito per eseguire un processo batch a un intervallo fisso e avere la possibilità di modificare l'ora di questo processo batch in fase di esecuzione. Per questo mi sono imbattuto nell'annotazione programmata fornita da Spring Framework. Ma non sono sicuro di come cambierei il valore di fixedDelay in fase di runtime. Ho fatto qualche ricerca su google, ma non ho trovato nulla di utile.Come modificare Spring @Scheduled fixedDelay a runtime
risposta
È possibile utilizzare un Trigger
per impostare dinamicamente il successivo tempo di esecuzione. Vedere la mia risposta qui:
Scheduling a job with Spring programmatically (with fixedRate set dynamically)
AFAIK l'API di primavera non ti consente di accedere agli interni necessari per modificare il trigger. Ma si potrebbe invece configurare manualmente i fagioli:
<bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
<property name="jobDetail" ref="jobDetail" />
<property name="startDelay" value="10000" />
<property name="repeatInterval" value="50000" />
</bean>
<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<property name="triggers">
<list>
<ref bean="simpleTrigger" />
</list>
</property>
</bean>
Poi, come documentato in SchedulerFactoryBean:
Per la registrazione dinamica di posti di lavoro in fase di esecuzione, utilizzare un riferimento fagiolo per questo SchedulerFactoryBean per ottenere l'accesso diretto al Quartz Scheduler (
org.quartz.Scheduler
). Ciò consente di creare nuovi job e trigger e anche di controllare e monitorare l'intero Pianificatore .
In avvio primavera, è possibile utilizzare una proprietà applicazione direttamente!
Ad esempio:
@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds}000")
private void process() {
// your impl here
}
Si noti che si può anche avere un valore di default nel caso in cui la proprietà non è definita, ad esempio, per avere un valore predefinito di "60" (secondi):
@Scheduled(fixedDelayString = "${my.property.fixed.delay.seconds:60}000")
Altre cose che ho scoperto:
- il metodo deve essere vuoto
- il metodo deve avere alcun parametro
- il metodo può essere
private
ho trovato essere in grado di utilizzare private
visibilità a portata di mano e lo ha utilizzato in questo modo:
@Service
public class MyService {
public void process() {
// do something
}
@Scheduled(fixedDelayString = "${my.poll.fixed.delay.seconds}000")
private void autoProcess() {
process();
}
}
Essere private
, il metodo pianificato può essere locale per il servizio e non diventare parte dell'API del servizio.
Inoltre, questo approccio consente al metodo process()
di restituire un valore, che potrebbe non essere un metodo @Scheduled
. Ad esempio, il metodo di process()
può assomigliare:
public ProcessResult process() {
// do something and collect information about what was done
return processResult;
}
di fornire alcune informazioni su quanto accaduto durante la lavorazione.
Grazie, 'fixedDelayString' è quello che stavo cercando – prettyvoid
Ottima risposta. Funziona come descritto. – flash
@Bohemain Grazie per la soluzione, ma come si aggiorna FixedDelay in fase di runtime? –
Vedo che hai accettato la risposta migliore, ma continuo a vedere che c'erano alcuni problemi irrisolti. Il problema NPE è stato risolto? È possibile che tu pubblichi l'intera soluzione per questo?Cheers – despot
Possibile duplicato di [Pianificazione di un lavoro con Spring a livello di codice (con fixedRate impostato dinamicamente)] (http://stackoverflow.com/questions/14630539/scheduling-a-job-with-spring-programmatically-with-fixedrate-set- dinamicamente) –