2016-05-19 8 views
5

uso avvio sprint 1.3, 4.2 mollaSchedule un'attività con Cron che consente l'aggiornamento dinamico

In questa classe

@Service 
public class PaymentServiceImpl implements PaymentService { 
    .... 
    @Transactional 
    @Override 
    public void processPayment() { 
     List<Payment> payments = paymentRepository.findDuePayment(); 
     processCreditCardPayment(payments); 
    } 
} 

desidero chiamare ProcessPayment ogni x istante.

Questo x momento è impostato in un database. L'utente può modificarlo.

Quindi penso di non poter usare l'anotazione.

ho iniziato a questo questo

@EntityScan(basePackageClasses = {MyApp.class,  Jsr310JpaConverters.class}) 
@SpringBootApplication 
@EnableCaching 
@EnableScheduling 
public class MyApp { 

    @Autowired 
    private DefaultConfigService defaultConfigService; 

    public static void main(String[] args) { 
     SpringApplication.run(MyApp.class, args); 
    } 

    @Bean 
    public TaskScheduler poolScheduler() { 
     SimpleAsyncTaskExecutor taskScheduler = new SimpleAsyncTaskExecutor(); 

     DefaultConfigDto defaultConfigDto = defaultConfigService.getByFieldName("payment-cron-task"); 
     String cronTabExpression = "0 0 4 * * ?"; 
     if (defaultConfigDto != null && !defaultConfigDto.getFieldValue().isEmpty()) { 
      cronTabExpression = "0 0 4 * * ?"; 
     } 

     appContext.getBean("scheduler"); 

     taskScheduler.schedule(task, new CronTrigger(cronTabExpression)); 
     return scheduler; 
    } 

Forse non è la strada buona.

Qualche suggerimento?

Non so se per ottenere il mio contesto, se ho bisogno di creare una proprietà come

@Autowired 
ConfigurableApplicationContext context; 

e un dopo nella principale

public static void main(String[] args) { 
     context = SpringApplication.run(MyApp.class, args); 
} 

risposta

7

Guardando la questione sembra che si desidera aggiornare lo scheduler, senza riavviare.

Il codice condiviso solo assicura che la configurazione venga selezionata dal DB, ma non verrà aggiornata senza il riavvio dell'applicazione.

Il seguente codice utilizza lo scheduler di default disponibili nel contesto primavera e calcolare dinamicamente il tempo di esecuzione successiva in base all'impostazione cron disponibili nel DB:

Ecco il codice di esempio:

import java.util.Date; 

import org.slf4j.Logger; 
import org.slf4j.LoggerFactory; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.scheduling.Trigger; 
import org.springframework.scheduling.TriggerContext; 
import org.springframework.scheduling.annotation.EnableScheduling; 
import org.springframework.scheduling.annotation.SchedulingConfigurer; 
import org.springframework.scheduling.config.ScheduledTaskRegistrar; 
import org.springframework.scheduling.support.CronTrigger; 

@SpringBootApplication 
@EnableScheduling 
public class Perses implements SchedulingConfigurer { 
    private static final Logger log = LoggerFactory.getLogger(Perses.class); 

    @Autowired 
    private DefaultConfigService defaultConfigService; 

    @Autowired 
    private PaymentService paymentService; 

    public static void main(String[] args) { 
     SpringApplication.run(Perses.class, args); 
    } 

    private String cronConfig() { 
     String cronTabExpression = "*/5 * * * * *"; 
     if (defaultConfigDto != null && !defaultConfigDto.getFieldValue().isEmpty()) { 
      cronTabExpression = "0 0 4 * * ?"; 
     } 
     return cronTabExpression; 
    } 

    @Override 
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 
     taskRegistrar.addTriggerTask(new Runnable() { 
      @Override 
      public void run() { 
       paymentService.processPayment(); 
      } 
     }, new Trigger() { 
      @Override 
      public Date nextExecutionTime(TriggerContext triggerContext) { 
       String cron = cronConfig(); 
       log.info(cron); 
       CronTrigger trigger = new CronTrigger(cron); 
       Date nextExec = trigger.nextExecutionTime(triggerContext); 
       return nextExec; 
      } 
     }); 
    } 
} 
+0

i ricerca per essere in grado di riflettere dinamicamente la modifica senza riavviare l'applicazione. –

+0

Aggiornato il codice java per avere cron dinamico. Spero che tu metta abbastanza guardie sul db entry, in modo che nessuno lo incasini. – Shibashis

+1

Mi piace il meccanismo. Abbiamo un modo per aggiornare il cron quando l'origine (file delle proprietà esterne, modifiche db, ecc.) Cambia? – Divs