一、使用@Schedule注解
@Schedule注解有一个缺点,其定时的时间不能动态的改变,改变周期需要重启服务
以下为三种方式:固定延迟时间、固定cron表达式、配置读取cron表达式
@Service
public class WsdlTask {
private final RawMaterialService rawMaterial;
@Autowired
public WsdlTask(RawMaterialService rawMaterial) {
this.rawMaterial = rawMaterial;
}
@Value("${factory}")
private String factory;
/**
* @description: 每30分钟获取Sap原材料库存
* @params: null
* @return: void
* @auther: WZH
* @date: 2019/9/20 12:29
*/
// @Scheduled(fixedDelay = 1000*60*30)
// @Scheduled(cron = "0 18/30 * * * ? ")
@Scheduled(cron = "${getRawMaterialCron}")
@Transactional(rollbackFor = Exception.class)
public void getRawMaterial(){
rawMaterial.getSap(factory);
}
}
二、基于SchedulingConfigurer接口
1、静态定时器
@Component
public class TaskConfig implements SchedulingConfigurer {
@Value("${csReportCron}")
private String csReportCron;
@Value("${factory}")
private String factory;
@Value("${scheduledOn}")
private Boolean scheduledOn;
private final WsdlTask wsdlTask;
@Autowired
public TaskConfig(WsdlTask wsdlTask) {
this.wsdlTask = wsdlTask;
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
//固定时间1秒
taskRegistrar.addFixedRateTask(() -> System.out.println("执行定时任务0: " + new Date()), 1000);
//Cron表达式
taskRegistrar.addCronTask(new CronTask(() -> System.out.println("执行定时任务1: " + new Date()),"*/2 * * * * ?"));
taskRegistrar.addCronTask(new CronTask(() -> System.out.println("执行定时任务2: " + new Date()),csReportCron));
taskRegistrar.addCronTask(new CronTask(() -> System.out.println("执行定时任务3: " + new Date()),new CronTrigger(csReportCron)));
//注册多个任务
taskRegistrar.addCronTask(() -> {
if(EnumModel.factory.CS01.name().equals(factory)&&scheduledOn){
wsdlTask.csReport();
}
}, csReportCron);
taskRegistrar.addCronTask(() -> {
if(EnumModel.factory.SM01.name().equals(factory)&&scheduledOn){
wsdlTask.smReport();
}
}, smReportCron);
taskRegistrar.addCronTask(wsdlTask::getRawMaterial, getRawMaterialCron);
}
}
2、动态定时器
基于SchedulingConfigurer接口的方式可以做到定时的时间动态改变,即从数据库中读取配置数据,控制是否开启定时任务和定时任务执行的周期
@Component
public class TaskConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
Runnable task= () -> System.out.println("执行动态定时任务"+new Date());
Trigger trigger= triggerContext -> {
String cron = "0/2 * * * * *";
CronTrigger cronTrigger=new CronTrigger(cron);
return cronTrigger.nextExecutionTime(triggerContext);
};
taskRegistrar.addTriggerTask(task, trigger);
taskRegistrar.addTriggerTask(
//1.添加任务内容(Runnable)
() -> System.out.println("执行动态定时任务: "+new Date()),
//2.设置执行周期(Trigger)
triggerContext -> {
//2.1 从数据库获取执行周期
String cron = "0/2 * * * * * ";
//2.2 合法性校验.
if (StringUtils.isEmpty(cron)) {
// Omitted Code ..
}
//2.3 返回执行周期(Date)
return new CronTrigger(cron).nextExecutionTime(triggerContext);
}
);
}
}
Controller控制改变请参考博文:https://www.jianshu.com/p/d557b2895b05
3、Timer
4、while循环sleep
五、QuartZ
请参考我的另一篇博文:SpringBoot整合QuartZ任务调度