最近项目中有关于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