2013-03-06 13 views
19

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

+0

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

+0

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) –

risposta

17

È 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)

+0

Esattamente quello che stavo cercando - Grazie amico – jsf

+0

FYI - Lasciato un commento sul bug 'NullPointerException' notato nel codice. – jsf

+0

C'è un modo per interrompere il Trigger corrente e cambiarne il valore mentre sta dormendo. – jsf

2

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 .

33

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.

+0

Grazie, 'fixedDelayString' è quello che stavo cercando – prettyvoid

+0

Ottima risposta. Funziona come descritto. – flash

+1

@Bohemain Grazie per la soluzione, ma come si aggiorna FixedDelay in fase di runtime? –

Problemi correlati