当前位置: 首页 > article >正文

SpringBoot 实现动态管理定时任务 Job的动态操作(添加、修改、启停、执行、删除)以及界面展示和具体Job的创建与执行示例

SpringBoot 实现动态管理定时任务 Job的动态操作(添加、修改、启停、执行、删除)以及界面展示和具体Job的创建与执行示例

关键接口类: CronTaskRegistrar SchedulingRunnable

. 添加定时任务注册类,用来增加、删除定时任务


import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import java.util.concurrent.ScheduledFuture;

/**
 * @description: 添加定时任务注册类,用来增加、删除定时任务。
 **/
@Component
public class CronTaskRegistrar implements DisposableBean {

    public static final Map<Runnable, ScheduledFuture<?>> scheduledTasks = new ConcurrentHashMap<>();
    public static final Map<String, Runnable> runnableMap = new ConcurrentHashMap<>();

    @Autowired
    private TaskScheduler taskScheduler;

    public TaskScheduler getScheduler() {
        return this.taskScheduler;
    }

    /**
     * 新增定时任务
     * @param task
     * @param cronExpression
     */
    public  void addCronTask(Runnable task, String cronExpression) {
        addCronTask(new CronTask(task, cronExpression));
    }

    public void addCronTask(CronTask cronTask) {
        if (cronTask != null) {
            Runnable task = cronTask.getRunnable();
            if (scheduledTasks.containsKey(task)) {
                removeCronTask(task);
            }
            scheduledTasks.put(task, scheduleCronTask(cronTask));
        }
    }


    /**
     * @description: 移除定时任务
     */
    public void removeCronTask(Runnable task) {
        ScheduledFuture<?> scheduledTask = scheduledTasks.get(task);
        if (scheduledTask != null) {
            scheduledTask.cancel(true);
            scheduledTasks.remove(task);
        }
    }

    public ScheduledFuture<?> scheduleCronTask(CronTask cronTask) {
        return this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
    }

    /**
    * @description: 定时任务销毁
    */
    @Override
    public void destroy() {
        for (ScheduledFuture<?> task : scheduledTasks.values()) {
            task.cancel(true);
        }
        scheduledTasks.clear();
    }
}

4、封装和执行定时任务


import com.yicheng.common.exception.UtilException;
import com.yicheng.common.utils.SpringContextUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.Objects;


public class SchedulingRunnable implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(SchedulingRunnable.class);

    private String runnableName;

    private String beanName;

    private String methodName;

    private Object[] params;

    public SchedulingRunnable(String beanName, String methodName) {
        this(beanName, methodName, null);
    }

    public SchedulingRunnable(String runnableName, String beanName, String methodName, Object... params) {
        this.runnableName = runnableName;
        this.beanName = beanName;
        this.methodName = methodName;
        this.params = params;
    }

    @Override
    public void run() {
        logger.info("定时任务开始执行 - bean:{},方法:{},参数:{}", beanName, methodName, params);
        long startTime = System.currentTimeMillis();
        try {
            Object target = SpringContextUtils.getBean(beanName);
            Method method = null;
            if (null != params && params.length > 0) {
                Class<?>[] paramCls = new Class[params.length];
                for (int i = 0; i < params.length; i++) {
                    paramCls[i] = params[i].getClass();
                }
                method = target.getClass().getDeclaredMethod(methodName, paramCls);
            } else {
                method = target.getClass().getDeclaredMethod(methodName);
            }

            ReflectionUtils.makeAccessible(method);
            if (null != params && params.length > 0) {
                method.invoke(target, params);
            } else {
                method.invoke(target);
            }
        } catch (Exception ex) {
            logger.error(String.format("定时任务执行异常 - bean:%s,方法:%s,参数:%s ", beanName, methodName, params), ex);
            throw new UtilException(ex);
        }
        long times = System.currentTimeMillis() - startTime;
        logger.info("定时任务执行结束 - bean:{},方法:{},参数:{},耗时:{} 毫秒", beanName, methodName, params, times);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        SchedulingRunnable that = (SchedulingRunnable) o;
        if (params == null) {
            return beanName.equals(that.beanName) &&
                    methodName.equals(that.methodName) &&
                    that.params == null;
        }
        return beanName.equals(that.beanName) &&
                methodName.equals(that.methodName) &&
                params.equals(that.params);
    }

    @Override
    public int hashCode() {
        if (params == null) {
            return Objects.hash(beanName, methodName);
        }
        return Objects.hash(beanName, methodName, params);
    }
}

4、防止 冲突 重新配置 TaskScheduler

@Configuration
public class SchedulerConfig {

    @Bean()
    public TaskScheduler taskScheduler() {
        return new ConcurrentTaskScheduler();
    }
}

5、任务执行业务




import com.yicheng.base.service.IVehicleService;
import com.yicheng.business.instruction.service.IIssuanceSevice;
import com.yicheng.business.ttsjob.domain.TbTtsJob;
import com.yicheng.business.ttsjob.service.ITbTtsJobService;
import com.yicheng.common.scheduler.CronTaskRegistrar;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


/**
 * @className: DoTask
 * @description: tts任务处理线程
 * @creat: 2025/1/10 15:05
 */
@Component("doTask")
public class DoTask {
    private static final Logger logger = LoggerFactory.getLogger(DoTask.class);
    public static final String jobNamePrefix = "ttsJob-";
    @Autowired
    private CronTaskRegistrar cronTaskRegistrar;
    @Autowired
    private ITbTtsJobService iTbTtsJobService;

    public DoTask() {

    }

    /**
     * 任务类型,1-立即执行,2-定时一次,3-每天固定时间执行
     *
     * @param runnableName
     * @param type
     * @param jobid
     */
    public void ttsSend(String runnableName, Integer type, Long jobid) {
        logger.info("即将执行ttsTask:type={}, jobid={}", type, jobid);
        TbTtsJob tbTtsJobs = iTbTtsJobService.getById(jobid);
        if (null == tbTtsJobs) {
            try {
                logger.info("未查询到ttsTask任务:type={}, jobid={},放弃执行", type, jobid);
                cronTaskRegistrar.removeCronTask(CronTaskRegistrar.runnableMap.get(runnableName));
                CronTaskRegistrar.runnableMap.remove(runnableName);
                return;
            }catch (Exception e){
                e.printStackTrace();
                return;
            }
        }
        if (tbTtsJobs.getStatus().intValue() == 1 || tbTtsJobs.getExecStatus().intValue() == 1) {
            // 任务未开启,直接结束,且清除任务
            cronTaskRegistrar.removeCronTask(CronTaskRegistrar.runnableMap.get(runnableName));
            CronTaskRegistrar.runnableMap.remove(runnableName);
        } else {
            if (tbTtsJobs.getType() == 1 || tbTtsJobs.getType() == 2) {
                tbTtsJobs.setExecStatus(1);
                tbTtsJobs.setStatus(1);
            }
            iTbTtsJobService.processJob(tbTtsJobs);
            logger.info("ttsTask任务进入执行队列:type={}, jobid={}", type, jobid);
        }
    }

}


创建表

CREATE TABLE `tb_tts_job` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `name` varchar(255) DEFAULT NULL COMMENT '任务名称',
  `content` text COMMENT '文本内容',
  `cron` varchar(255) DEFAULT NULL COMMENT '定时标识',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `status` int(1) DEFAULT NULL COMMENT '状态,1-未开启,0-已开启',
  `exec_status` int(2) DEFAULT NULL COMMENT '执行状态 0-生效 1-已关闭',
  `type` int(1) DEFAULT NULL COMMENT '任务类型,1-立即执行,2-定时一次,3-每天固定时间执行',
  `do_time` datetime DEFAULT NULL COMMENT '执行时间',
  `last_do_time` datetime DEFAULT NULL COMMENT '最近执行时间',
  `index_type` varchar(1) DEFAULT NULL COMMENT '指令类型',
  `run_time` varchar(20) DEFAULT NULL COMMENT '时间',
  `run_date_time` varchar(30) DEFAULT NULL COMMENT '日期',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='tts语音定时任务';

启动项目加载定时任务

package com.yicheng.web.controller.common;

import com.yicheng.business.ttsjob.domain.TbTtsJob;
import com.yicheng.business.ttsjob.service.ITbTtsJobService;
import com.yicheng.business.ttsjob.task.DoTask;
import com.yicheng.common.scheduler.CronTaskRegistrar;
import com.yicheng.common.scheduler.SchedulingRunnable;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 项目启动后加载动态定时任务
 */
@Slf4j
@Component
public class JobsLoader implements ApplicationRunner {
    private static final Logger logger = LoggerFactory.getLogger(JobsLoader.class);
    @Autowired
    private ITbTtsJobService iTbTtsJobsService;
    @Autowired
    private CronTaskRegistrar cronTaskRegistrar;

    /**
     * 项目启动后加载动态定时任务
     * @param args
     * @throws Exception
     */
    @Override
    public void run(ApplicationArguments args) throws Exception {
        ttsTaskLoader();
    }

    /**
    * @description: 加载定时发送任务
    * @create: 2025/01/10 15:50
    * @param:
    * @return:
    */
    public void ttsTaskLoader() {
        List<TbTtsJob> tbTtsJobs = iTbTtsJobsService.selectTtsJobList();
        tbTtsJobs.forEach(ttsJob -> {
            String runnableName = DoTask.jobNamePrefix + ttsJob.getId();
            SchedulingRunnable task = new SchedulingRunnable(runnableName, "doTask", "ttsSend", runnableName, ttsJob.getType(), ttsJob.getId());
            cronTaskRegistrar.addCronTask(task, ttsJob.getCron());
            CronTaskRegistrar.runnableMap.put(runnableName, task);
        });
        logger.info("启动加载动态定时任务[Job],共{}条", tbTtsJobs.size());
    }

}

任务的新增、和移除
Controller



import com.yicheng.business.ttsjob.domain.TbTtsJob;
import com.yicheng.business.ttsjob.service.ITbTtsJobService;
import com.yicheng.common.core.page.TableDataInfo;
import com.yicheng.common.core.controller.BaseController;
import com.yicheng.common.core.domain.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.text.ParseException;
import java.util.List;

/**
 * @className: TtsJobsController
 * @description: 定时指令下发控制器
 * @creat: 2025/1/10 14:06
 */
@RestController
@RequestMapping("/business/ttsJob")
public class TtsJobsController extends BaseController {

    @Autowired
    private ITbTtsJobService iTbTtsJobsService;


    /**
    * @description: tts定时任务列表
    * @create: 2025/01/13 11:47
    * @param:
    * @return:
    */
    @GetMapping("/list")
    public TableDataInfo list(TbTtsJob ttsJobs) {
        startPage();
        List<TbTtsJob> tbTtsJobs = iTbTtsJobsService.selectTtsJobList(ttsJobs);
        return getDataTable(tbTtsJobs);
    }


    /**
     * @description: 新增定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    @ResponseBody
    @PostMapping("/addJob")
    public R<Integer> addJob(@RequestBody TbTtsJob ttsJobs) {
        try {
            return R.ok(iTbTtsJobsService.addTtsJob(ttsJobs));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * @description: 新增定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    @ResponseBody
    @PostMapping("/updateJob")
    public R<Integer> updateJob(@RequestBody TbTtsJob ttsJobs) {
        try {
            return R.ok(iTbTtsJobsService.update(ttsJobs));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }



    /**
     * @description: 启停定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */

    @ResponseBody
    @PutMapping("/changeStatus")
    public R changeStatus(@RequestBody TbTtsJob ttsJobs) throws ParseException {
        return R.ok(iTbTtsJobsService.open(ttsJobs));
    }


    /**
     * @description: 定时任务详情
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    @GetMapping("/detail/{id}")
    public R<TbTtsJob> detail(@PathVariable Integer id) {
        TbTtsJob tbTtsJob= iTbTtsJobsService.detail(id);
        return R.ok(tbTtsJob);
    }


    /**
     * @description: 删除定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    @DeleteMapping("/{id}")
    public R remove(@PathVariable Integer id) {
        return R.ok(iTbTtsJobsService.remove(id));
    }
}

service

import com.baomidou.mybatisplus.extension.service.IService;
import com.yicheng.business.ttsjob.domain.TbTtsJob;
import com.yicheng.business.ttsjob.domain.vo.TtsTaskVo;
import org.springframework.scheduling.annotation.Async;

import java.util.List;


/**
 * @className: ITbTtsJobService
 * @description: tts任务表服务接口
 * @creat: 2025/1/10 15:05
 */
public interface ITbTtsJobService extends IService<TbTtsJob> {

    /**
     * @description: tts定时任务列表
     * @create: 2025/01/13 11:47
     * @param:
     * @return:
     */
    List<TbTtsJob> selectTtsJobList(TbTtsJob tbTtsJob);



    List<TbTtsJob> selectTtsJobList();

    /**
     * @description: 新增定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    int addTtsJob(TbTtsJob tbTtsJob) throws Exception ;

    /**
     * @description: 新增定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    int update(TbTtsJob tbTtsJob) throws Exception ;

    /**
     * @description: 启停定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    int open(TbTtsJob tbTtsJob);


    /**
     * @description: 定时任务详情
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    TbTtsJob detail(Integer id);

    /**
     * @description: 删除定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    int remove(Integer id);


    void processJob(TbTtsJob tbTtsJobs);

}

impl

package com.yicheng.business.ttsjob.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yicheng.base.service.IVehicleService;
import com.yicheng.business.instruction.domain.vo.textIssuanceRequset;
import com.yicheng.business.instruction.service.IIssuanceSevice;
import com.yicheng.business.ttsjob.domain.TbTtsJob;
import com.yicheng.business.ttsjob.mapper.TbTtsJobMapper;
import com.yicheng.business.ttsjob.service.ITbTtsJobService;
import com.yicheng.business.ttsjob.task.DoTask;
import com.yicheng.common.annotation.DataScope;
import com.yicheng.common.scheduler.CronTaskRegistrar;
import com.yicheng.common.scheduler.SchedulingRunnable;
import com.yicheng.common.utils.DateCronUtil;
import com.yicheng.common.utils.DateUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.yicheng.common.utils.SecurityUtils.*;


/**
 * tts语音定时任务Service业务层处理
 *
 * @author yicheng
 * @date 2025-01-10
 */
@Service
public class TbTtsJobServiceImpl extends ServiceImpl<TbTtsJobMapper, TbTtsJob> implements ITbTtsJobService {

    private static final Logger logger = LoggerFactory.getLogger(TbTtsJobServiceImpl.class);

    @Autowired
    private TbTtsJobMapper tbTtsJobMapper;

    @Autowired
    private CronTaskRegistrar cronTaskRegistrar;

    @Autowired
    private IVehicleService iTbVehicleService;

    @Autowired
    private IIssuanceSevice iIssuanceSevice;

    /**
     * @description: tts定时任务列表
     * @create: 2025/01/13 11:47
     * @param:
     * @return:
     */
    @Override
    public List<TbTtsJob> selectTtsJobList(TbTtsJob tbTtsJob) {
        tbTtsJob.setGroupId(getDeptId());
        List<TbTtsJob> tbTtsJobs = tbTtsJobMapper.selectTtsJobPageList(tbTtsJob);
        return tbTtsJobs;
    }


    @Override
    public List<TbTtsJob> selectTtsJobList() {
        return tbTtsJobMapper.selectTtsJobList();
    }

    /**
     * @description: 新增定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    @Override
    public int addTtsJob(TbTtsJob ttsJobs) throws Exception {
        SimpleDateFormat sdfDt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
     
        // 任务类型,1-立即执行,2-定时一次,3-每天固定时间执行
        // 立即执行,默认2分钟后执行
        if (ttsJobs.getType() == 1) {
            ttsJobs.setStatus(0);
            ttsJobs.setExecStatus(0);
            Calendar beforeTime = Calendar.getInstance();
            // 30秒之后的时间
            beforeTime.add(Calendar.SECOND, 30);
            Date date = beforeTime.getTime();
            String cron = DateCronUtil.getCron(date);
            // spring task cron不支持年
            int index = cron.lastIndexOf(" ");
            cron = cron.substring(0, index);
            ttsJobs.setCron(cron);
            ttsJobs.setDoTime(date);
        } else if (ttsJobs.getType() == 2) {
            ttsJobs.setStatus(0);
            ttsJobs.setExecStatus(0);
            String oneceTime = ttsJobs.getRunDateTime();
            Date date = sdfDt.parse(oneceTime);
            String cron = DateCronUtil.getCron(date);
            // spring task cron不支持年
            int index = cron.lastIndexOf(" ");
            cron = cron.substring(0, index);
            ttsJobs.setCron(cron);
            ttsJobs.setDoTime(date);
        } else {
            ttsJobs.setStatus(0);
            ttsJobs.setExecStatus(0);
            String everyDayTime = ttsJobs.getRunTime();
            String timeStr = sdf.format(new Date()) + " " + everyDayTime;
            Date date = sdfDt.parse(timeStr);
            String cronTmp = DateCronUtil.getCron(date);
            String[] cronTmpArr = cronTmp.split(" ");
            String cron = cronTmpArr[0] + " " + cronTmpArr[1] + " " + cronTmpArr[2] + " * * ? *";
            // spring task cron不支持年
            int index = cron.lastIndexOf(" ");
            cron = cron.substring(0, index);
            ttsJobs.setCron(cron);
            ttsJobs.setRunTime(timeStr);
        }
        int result =tbTtsJobMapper.insert(ttsJobs);
        String runnableName = DoTask.jobNamePrefix + ttsJobs.getId();
        SchedulingRunnable task = new SchedulingRunnable(runnableName, "doTask", "ttsSend", runnableName, ttsJobs.getType(), ttsJobs.getId());
        cronTaskRegistrar.addCronTask(task, ttsJobs.getCron());
        CronTaskRegistrar.runnableMap.put(runnableName, task);
        logger.info("AddCronTask is OK!");
        return result;
    }

    @Override
    public int update(TbTtsJob ttsJobs) throws Exception {
        SimpleDateFormat sdfDt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        // 任务类型,1-立即执行,2-定时一次,3-每天固定时间执行
        // 立即执行,默认2分钟后执行
        if (ttsJobs.getType() == 1) {
            ttsJobs.setExecStatus(0);
            Calendar beforeTime = Calendar.getInstance();
            // 30秒之后的时间
            beforeTime.add(Calendar.SECOND, 30);
            Date date = beforeTime.getTime();
            String cron = DateCronUtil.getCron(date);
            // spring task cron不支持年
            int index = cron.lastIndexOf(" ");
            cron = cron.substring(0, index);
            ttsJobs.setCron(cron);
            ttsJobs.setDoTime(date);
        } else if (ttsJobs.getType() == 2) {
            ttsJobs.setExecStatus(0);
            String oneceTime = ttsJobs.getRunDateTime();
            Date date = sdfDt.parse(oneceTime);
            String cron = DateCronUtil.getCron(date);
            // spring task cron不支持年
            int index = cron.lastIndexOf(" ");
            cron = cron.substring(0, index);
            ttsJobs.setCron(cron);
            ttsJobs.setDoTime(date);
        } else {
            ttsJobs.setExecStatus(0);
            String everyDayTime = ttsJobs.getRunTime();
            String timeStr = sdf.format(new Date()) + " " + everyDayTime;
            Date date = sdfDt.parse(timeStr);
            String cronTmp = DateCronUtil.getCron(date);
            String[] cronTmpArr = cronTmp.split(" ");
            String cron = cronTmpArr[0] + " " + cronTmpArr[1] + " " + cronTmpArr[2] + " * * ? *";
            // spring task cron不支持年
            int index = cron.lastIndexOf(" ");
            cron = cron.substring(0, index);
            ttsJobs.setCron(cron);
            ttsJobs.setRunTime(timeStr);
        }
        if(ttsJobs.getStatus() == 0){
            String runnableName_del = DoTask.jobNamePrefix + ttsJobs.getId();
            cronTaskRegistrar.removeCronTask(CronTaskRegistrar.runnableMap.get(runnableName_del));
            CronTaskRegistrar.runnableMap.remove(runnableName_del);

            String runnableName = DoTask.jobNamePrefix + ttsJobs.getId();
            SchedulingRunnable task = new SchedulingRunnable(runnableName, "doTask", "ttsSend", runnableName, ttsJobs.getType(), ttsJobs.getId());
            cronTaskRegistrar.addCronTask(task, ttsJobs.getCron());
            CronTaskRegistrar.runnableMap.put(runnableName, task);
        }
        ttsJobs.setLastDoTime(null);
        int result =tbTtsJobMapper.updateById(ttsJobs);
        return result;
    }

    /**
     * @description: 启停定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    @Override
    public int open(TbTtsJob tbTtsJob) {
        TbTtsJob updateJob = tbTtsJobMapper.selectById(tbTtsJob.getId());
        try {
            if (tbTtsJob.getStatus().intValue() == 0) {
                String runnableName = DoTask.jobNamePrefix + updateJob.getId();
                SchedulingRunnable task = new SchedulingRunnable(runnableName, "doTask", "ttsSend", runnableName, updateJob.getType(), updateJob.getId());
                cronTaskRegistrar.addCronTask(task, updateJob.getCron());
                CronTaskRegistrar.runnableMap.put(runnableName, task);
            } else {
                String runnableName = DoTask.jobNamePrefix + updateJob.getId();
                cronTaskRegistrar.removeCronTask(CronTaskRegistrar.runnableMap.get(runnableName));
                CronTaskRegistrar.runnableMap.remove(runnableName);
            }
        }catch (Exception e) {
            logger.error("open error:{}", e);
        }
        updateJob.setStatus(tbTtsJob.getStatus());
        return tbTtsJobMapper.updateById(updateJob);
    }

    @Override
    public TbTtsJob detail(Integer id) {
        TbTtsJob updateJob = tbTtsJobMapper.selectById(id);
        return updateJob;
    }

    /**
     * @description: 删除定时任务
     * @create: 2025/01/10 14:07
     * @param:
     * @return:
     */
    @Override
    public int remove(Integer id) {
        try {
            TbTtsJob tbTtsJob = tbTtsJobMapper.selectById(id);
            String runnableName = DoTask.jobNamePrefix + tbTtsJob.getId();
            cronTaskRegistrar.removeCronTask(CronTaskRegistrar.runnableMap.get(runnableName));
            CronTaskRegistrar.runnableMap.remove(runnableName);
        }catch (Exception e){
            e.printStackTrace();
        }
        return tbTtsJobMapper.deleteById(id);
    }


    @Async
    @Override
    public void processJob(TbTtsJob tbTtsJobs) {
        String groupIdsString = tbTtsJobs.getGroupIds();
        Set<Long> groupIds = Arrays.stream(groupIdsString.split(","))
                .map(String::trim)
                .map(Long::parseLong)
                .collect(Collectors.toSet());
        List<String> commNos = iTbVehicleService.getCommNos(groupIds, tbTtsJobs.getVehicleType());
        textIssuanceRequset textRequset = new textIssuanceRequset();
        textRequset.setSendType(2);
        textRequset.setPhoneNo(commNos.stream().collect(Collectors.joining(",")));
        textRequset.setContent(tbTtsJobs.getContent());
        textRequset.setMessageType(Arrays.asList(3));
        tbTtsJobs.setLastDoTime(DateUtils.getNowDate());
        tbTtsJobMapper.updateById(tbTtsJobs);
        iIssuanceSevice.sendTextByTaskJob(textRequset);
        logger.info("Processing task is OK!");
    }
}

根据日期生成cron

package com.yicheng.common.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;


/**
 * @className: DateCronUtil
 * @description: 日期与cron表达式 转换工具类
 * @author: zhuYaqiang
 * @creat: 2025/1/10 14:06
 */
public class DateCronUtil {

    /**
     * 日期转化为cron表达式
     * @param date
     * @return
     */
    public static String getCron(Date  date){
        String dateFormat="ss mm HH dd MM ? yyyy";
        return  DateCronUtil.fmtDateToStr(date, dateFormat);
    }

    /**
     * cron表达式转为日期
     * @param cron
     * @return
     */
    public static Date getCronToDate(String cron) {
        String dateFormat="ss mm HH dd MM ? yyyy";
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        Date date = null;
        try {
            date = sdf.parse(cron);
        } catch (ParseException e) {
            return null;
        }
        return date;
    }

    /**
     * Description:格式化日期,String字符串转化为Date
     *
     * @param date
     * @param dtFormat
     *            例如:yyyy-MM-dd HH:mm:ss yyyyMMdd
     * @return
     */
    public static String fmtDateToStr(Date date, String dtFormat) {
        if (date == null) {
            return "";
        }
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(dtFormat);
            return dateFormat.format(date);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }
}

前端页面截图
在这里插入图片描述

在这里插入图片描述

至此:springboot +scheduler+cron 实现动态定时任务 简单实现 , 有需要的可以点赞 收藏哦


http://www.kler.cn/a/515500.html

相关文章:

  • 99.6 金融难点通俗解释:股息率(DV)
  • 【深度学习基础】多层感知机 | 权重衰减
  • (长期更新)《零基础入门 ArcGIS(ArcMap) 》实验六----流域综合处理(超超超详细!!!)
  • 接口 V2 完善:基于责任链模式、Canal 监听 Binlog 实现数据库、缓存的库存最终一致性
  • Qt —— 控件属性
  • AIGC视频生成国产之光:ByteDance的PixelDance模型
  • 使用sql查询excel内容
  • 学习ASP.NET Core的身份认证(基于JwtBearer的身份认证6)
  • Django 的 `Meta` 类和外键的使用
  • 数据分析 变异系数
  • 设计模式-模板方法实现
  • css普通用法
  • APL语言的物联网
  • epoll 的边缘触发(Edge Triggered)与水平触发(Level Triggered)
  • 不同IO模型服务器的简单实现
  • 【R语言】数学运算
  • 迷你世界玩家准备界面UI设计制作触发器
  • QT+VS2022 应用程序无法启动0x000007b问题记录
  • Linux环境部署——MySQL忘记密码
  • 【Java】Java抛异常到用户界面公共封装
  • 分享一款WebSocket在线测试工具,使用简单方便
  • 《探秘:人工智能如何为鸿蒙Next元宇宙网络传输与延迟问题破局》
  • springBoot tomcat
  • 【玩转全栈】----用户管理案例
  • 信号失真度测试仪、音频失真度测试仪、失真度仪、全自动数字失真度测量仪
  • 没有公网IP实现seafile本地IP访问和虚拟局域网IP同时访问和上传文件