使用Cron安排任务,允许动态更新

rob*_*non 7 spring spring-scheduled spring-boot

我使用sprint boot 1.3,spring 4.2

在这堂课上

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

我想每隔x刻拨打一次processPayment.

此x时刻在数据库中设置.用户可以修改它.

所以我想我不能使用anotation.

我开始这样做了

@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;
    }
Run Code Online (Sandbox Code Playgroud)

也许这不是好方法.

有什么建议吗?

如果我需要创建一个属性,不知道是否获取我的上下文

@Autowired
ConfigurableApplicationContext context;
Run Code Online (Sandbox Code Playgroud)

在主要之后

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

Shi*_*his 12

看看这个问题似乎想要更新调度程序,而无需重新启动.

您共享的代码仅确保从数据库中选择配置,但如果没有重新启动应用程序,它将无法刷新.

以下代码将使用spring上下文中提供的默认调度程序,并根据DB中可用的cron设置动态计算下一个执行时间:

以下是示例代码:

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;
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 喜欢这个机制。当源(外部属性文件、数据库更改等)发生变化时,我们有什么方法可以更新 cron 吗? (2认同)
  • 我认为这个问题的关键在于是否可以动态更新cron任务,而不仅仅是从数据库中读取一次.你能提供这方面的任何信息吗? (2认同)