SpringBoot实现动态定时任务

2023年2月4日10:55:42

项目情况:

         在当前项目中需要一个定时任务来清除过期的校验码,如果使用数据库存储过程的话不方便维护。因此采用SpringBoot自带的方式来设置定时任务。

技术说明:

         SpringBoot自带的方式有两种可以实现:

        一种是使用@Scheduled注解的方式,只需要在启动类或者它所在的类上添加@EnableScheduling注解允许执行定时任务,并且设置Schecduled注解的参数,诸如:

        1.cron是设置定时执行的表达式,如 0 0/5 * * * ?每隔五分钟执行一次

        2.zone表示执行时间的时区

        3.fixedDelay 和fixedDelayString 表示一个固定延迟时间执行,上个任务完成后,延迟多长时间执行

        4.fixedRate 和fixedRateString表示一个固定频率执行,上个任务开始后,多长时间后开始执行

        5.initialDelay 和initialDelayString表示一个初始延迟时间,第一次被调用前延迟的时间

    示例代码如下:

package com.allcom.service;

import com.allcom.dao.MysqlDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

/**
* @Author: zy
* @Description: 定时任务
* @Date: 2018/7/12_15:15
**/
@Service
public class TaskService {

    @Autowired
    private MysqlDao mysqlDao;

    @Scheduled(fixedRate = 5*1000)
    public void deleteInvalidCheckCode() {
        mysqlDao.deleteInvalidCheckCode();
    }


}

         另一种方式是通过自定义配置类的方式,步骤如下:

         第一步:新建一个类实现SchedulingConfigurer接口,并添加@Configuration注解,@EnableScheduling注解可以写在这里也可以写在启动类上,这里我写在了启动类上。

    SpringBoot实现动态定时任务

          第二步: 重写configureTasks方法如下代码所示:

package com.allcom.task;

import com.allcom.service.TaskService;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;



import java.util.Date;


@Configuration
public class MyScheduledTask implements SchedulingConfigurer {

    @Mapper
    public interface CronMapper {
        @Select("select cron from user_cron limit 1")
        String getCron();
    }

    @Autowired
    @SuppressWarnings("all")
    CronMapper cronMapper;


    @Autowired
    @SuppressWarnings("all")
    private TaskService taskService;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
           scheduledTaskRegistrar.addTriggerTask(new Runnable() {
               @Override
               public void run() {
                   try {
                       taskService.deleteInvalidCheckCode();  //异步定时操作
                   } catch (Exception e) {
                       e.printStackTrace();
                   }
               }
           }, new Trigger() {
               @Override
               public Date nextExecutionTime(TriggerContext triggerContext) {
                   String cron =cronMapper.getCron();
                    if("".equals(cron)||cron==null)
                        return null;
                   //定时任务触发,可修改定时任务的执行周期
                   CronTrigger trigger=new CronTrigger(cron);
                   Date nextExecDate= trigger.nextExecutionTime(triggerContext);
                   return nextExecDate;
               }
           });
    }
}

              第三步:启动项目,定时任务就自动添加了。

   注意:这里我使用的是@Mapper注解使用Mybatis写了一个获取cron表达式的接口,可以从数据库中查询自定义表的cron字段值。这样的话项目运行的过程中,不用重新启动项目,只需要修改数据库中的字段值就可以动态的修改定时任务中的cron值,实现动态修改定时任务执行时间的功能。

          但是,这种方式有一个缺点就是,将数据库cron字段值设为null或者“”以及不正确的值,这样定时任务就会停止执行,这样就算你下一次再给cron字段添加了正确的值,项目也不会执行定时任务了,这个时候就需要重新启动数据库才行。

          这种方式适合于前台给几个特定的值给用户选择,不能让用户随便填。

附定时任务执行内容:

/**
* @Author: zy
* @Description: 删除用户过期的校验码
* @Date: 2018/7/12_15:20
**/
@Delete("DELETE from registinfo where id in (select id from (SELECT id FROM registinfo WHERE TIMESTAMPDIFF(MINUTE,lastupdatetime,NOW()) >= 15)a )")
void deleteInvalidCheckCode();

  • 作者:我滴太阳233
  • 原文链接:https://blog.csdn.net/qq_31247177/article/details/81019557
    更新时间:2023年2月4日10:55:42 ,共 3071 字。