最近项目中有关于springboot中动态配置定时任务的需求,查阅各种资料,最终实现了可以动态的开关定时器,以及配置定时器的时间节点。
网上有很多关于springboot定时任务的介绍,之前项目中也用过quartz,和springboot中自带的@Schedule相比较,配置稍显复杂。本篇幅只介绍@Schedule的用法。
网上有很多关于springboot定时任务的文章,大部分都是静态配置,本篇主要介绍动态配置定时任务,且不需要重启项目:
关于新建springboot项目,我就不絮叨了,直接进正题:
一:springboot配置静态定时任务
1:pom中添加依赖
2:启动类中加入@EnableScheduling来开启定时任务
3:@Scheduled(cron = "0/10* * * * ?")// 每过10秒执行一次
静态配置就说这些,网上资料非常多,主要说一下动态配置定时任务。
二:springboot动态配置定时任务
项目接到需求后,经过分析,决定将cron持久化至数据库中,实现动态修改定时任务的周期,并且可以通过前后台交互,实现页面更改,本篇幅只介绍到controller层,前台js,ajax,各位小友可以根据项目需求自行添加。
config(核心):
/**
* Created by zhangdd on 2018/1/15 0015.
*/
@Component
public class ScheduleConfig {
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
return new ThreadPoolTaskScheduler();
}
private ScheduledFuture<?> future;
private String cron = "";
public String getCron() {
return cron;
}
public void stopCron() {
if (future != null) {
//取消定时任务
future.cancel(true);
}
}
public void setCron(String cron) {
this.cron = cron;
stopCron();
future = threadPoolTaskScheduler.schedule(new Runnable() {
@Override
public void run() {
try {
System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
if ("".equals(cron) || cron == null) {
return null;
}
// 定时任务触发,可修改定时任务的执行周期
CronTrigger trigger = new CronTrigger(cron);
Date nextExecDate = trigger.nextExecutionTime(triggerContext);
return nextExecDate;
}
});
}
}
Cron(实体类):
/**
* Created by zhangdd on 2018/1/15 0015.
*/
@Entity
public class Cron {
@Id
@GeneratedValue
private Integer no;
/**
* cron_id
*/
private String cronId;
/**
* cron
*/
private String cron;
/**
* 状态("1":有效 "0":无效)
*/
private String status;
public Cron() {
}
public Integer getNo() {
return no;
}
public void setNo(Integer no) {
this.no = no;
}
public String getCronId() {
return cronId;
}
public void setCronId(String cronId) {
this.cronId = cronId;
}
public String getCron() {
return cron;
}
public void setCron(String cron) {
this.cron = cron;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
}
Dao:
/**
* Created by zhangdd on 2018/1/15 0015.
*/
public interface CronDao extends CrudRepository<Cron,Integer> {
public Cron findByCronIdAndStatus(String cronId,String status);
}
Service:
/**
* Created by zhangdd on 2018/1/15 0015.
*/
@Service
public class CronServiceImpl implements CronService {
@Autowired
private CronDao cronDao;
@Override
public Cron findByCronIdAndStatus(String cronId,String status) {
return cronDao.findByCronIdAndStatus(cronId,status);
}
}
Controller:
/**
* (开启定时任务)
*/
@RequestMapping("/startPay")
@ResponseBody
public String payFee() {
String cron = cronService.findByCronIdAndStatus("1","1").getCron();
if(!StringUtils.isEmpty(cron)) {
scheduleConfig.setCron(cron);
logger.info("开启定时任务成功");
return "开启定时任务成功";
} else {
logger.error("开启定时任务失败");
return "开启定时任务失败";
}
}
/**
* (关闭定时任务)
*/
@RequestMapping("/closePay")
@ResponseBody
public String closePayFee() {
try {
scheduleConfig.stopCron();
logger.info("关闭定时任务成功");
return "关闭定时任务成功";
}catch (Exception e){
logger.error("关闭定时任务失败");
}
return "关闭定时任务失败";
}
以上,从config到controller,可以实现动态开启关闭定时任务,并且不需要重启项目,各位小友可以根据自身项目需求自行做出更改,如嵌入前台页面进行交互,亲测是可用的。本文是自己的理解,如果小友觉得有什么不对的地方,欢迎一起讨论。
最后加上项目的结构:
com.zdd
config
entity
dao
service
impl
controller