日前项目中遇到一个需求,需要客户能在项目运行中修改定时器的策略,而不用重启,就不能用@cron来制定定时器策略,这个需求还算比较常见,故记录下来,方便以后。
先新建一个接口
package com.jrzh.mvc.schedule;
import java.util.concurrent.ScheduledFuture;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.jrzh.framework.bean.ResultBean;
import com.jrzh.mvc.task.batchDeduction;
import com.jrzh.mvc.task.reconciliationEveryDay;
import com.jrzh.mvc.task.singleDeduction;
@RestController(ScheduleApplication.LOCATION +"/ScheduleApplication")
@RequestMapping(ScheduleApplication.LOCATION)
@SpringBootApplication
public class ScheduleApplication {
public static final String LOCATION = "pay/scheduleApplication";
// 建立三条定时线程
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskSchedulerr;
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskSchedulerrr;
// 定义三个bean
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
return new ThreadPoolTaskScheduler();
}
@Bean
public ThreadPoolTaskScheduler threadPoolTaskSchedulerr(){
return new ThreadPoolTaskScheduler();
}
@Bean
public ThreadPoolTaskScheduler threadPoolTaskSchedulerrr(){
return new ThreadPoolTaskScheduler();
}
// 定义任务处理结果
private ScheduledFuture<?> deduction;
private ScheduledFuture<?> reconciliation;
private ScheduledFuture<?> singleDeduction;
// 定义接口调用
@PostMapping("/startCron")
@ResponseBody
public ResultBean startCron(String cron,String name){
ResultBean result = new ResultBean();
// 接口调用,根据name来识别是什么线程,cron则为定时策略
if (StringUtils.equals("xxx", name)) {
if(deduction != null) {
deduction.cancel(true);
}
// batchDeduction在下面
deduction = threadPoolTaskScheduler.schedule(new batchDeduction(), new CronTrigger(cron));
} else if (StringUtils.equals("yyy", name)) {
if(reconciliation != null) {
reconciliation.cancel(true);
}
reconciliation = threadPoolTaskSchedulerr.schedule(new reconciliationEveryDay(), new CronTrigger(cron));
} else if (StringUtils.equals("zzz", name)) {
if(singleDeduction != null) {
singleDeduction.cancel(true);
}
singleDeduction = threadPoolTaskSchedulerrr.schedule(new singleDeduction(), new CronTrigger(cron));
}else {
// 如果找不到线程则不做操作
}
result.setStatus(ResultBean.SUCCESS);
return result;
}
}
定时器方法,去掉@cron注解,其两个方法不做展示
package com.jrzh.mvc.task;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import com.jrzh.framework.SpringContextUtil;
import com.jrzh.framework.base.controller.BaseAdminController;
import com.jrzh.framework.bean.ResultBean;
import com.jrzh.framework.bean.SessionUser;
import com.jrzh.mvc.contants.PayContants;
import com.jrzh.mvc.model.pay.PayTimingResultModel;
import com.jrzh.mvc.service.pay.PayEtcFlowServiceI;
import com.jrzh.mvc.service.pay.PayTimingResultServiceI;
import com.jrzh.mvc.service.pay.PayTimingServiceI;
@Component
public class batchDeduction extends BaseAdminController implements Runnable {
@Override
public void run() {
try {
long startTime = System.currentTimeMillis();
PayEtcFlowServiceI payEtcFlowService = SpringContextUtil.getBean("payEtcFlowService");
ResultBean result = payEtcFlowService.ccfHuakou();
System.out.println("批量扣款文件");
// 计算定时任务所花时间
long endTime = System.currentTimeMillis();
long timeConsum = endTime - startTime;
PayTimingResultModel ptrModel = new PayTimingResultModel();
Date date = new Date();
date.setTime(startTime);
ptrModel.setBeginTime(date);
date.setTime(endTime);
ptrModel.setEndTime(date);
ptrModel.setUseTime((int) timeConsum);
ptrModel.setExecutionType(PayContants.EXCUTION_TYPE.ZD);
PayTimingServiceI payTimingService = SpringContextUtil.getBean("payTimingService");
ptrModel.setTimingId(payTimingService.findByField("taskName", "批量扣款获取").getId());
if (StringUtils.equals("success", result.getStatus())) {
ptrModel.setResult("成功");
} else {
ptrModel.setResult("失败");
}
PayTimingResultServiceI payTimingResultService = SpringContextUtil.getBean("payTimingResultService");
payTimingResultService.add(ptrModel, SessionUser.getSystemUser());
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void setData() {
// TODO Auto-generated method stub
}
}
在前端写一个输入框接收cron表达式,然后修改完再调用/startCron接口,就能实现通过