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<>();@Autowiredprivate 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: 定时任务销毁*/@Overridepublic 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;}@Overridepublic 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);}@Overridepublic 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) &¶ms.equals(that.params);}@Overridepublic 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-";@Autowiredprivate CronTaskRegistrar cronTaskRegistrar;@Autowiredprivate 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);@Autowiredprivate ITbTtsJobService iTbTtsJobsService;@Autowiredprivate CronTaskRegistrar cronTaskRegistrar;/*** 项目启动后加载动态定时任务* @param args* @throws Exception*/@Overridepublic 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 {@Autowiredprivate 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);@Autowiredprivate TbTtsJobMapper tbTtsJobMapper;@Autowiredprivate CronTaskRegistrar cronTaskRegistrar;@Autowiredprivate IVehicleService iTbVehicleService;@Autowiredprivate IIssuanceSevice iIssuanceSevice;/*** @description: tts定时任务列表* @create: 2025/01/13 11:47* @param:* @return:*/@Overridepublic List<TbTtsJob> selectTtsJobList(TbTtsJob tbTtsJob) {tbTtsJob.setGroupId(getDeptId());List<TbTtsJob> tbTtsJobs = tbTtsJobMapper.selectTtsJobPageList(tbTtsJob);return tbTtsJobs;}@Overridepublic List<TbTtsJob> selectTtsJobList() {return tbTtsJobMapper.selectTtsJobList();}/*** @description: 新增定时任务* @create: 2025/01/10 14:07* @param:* @return:*/@Overridepublic 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;}@Overridepublic 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:*/@Overridepublic 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);}@Overridepublic TbTtsJob detail(Integer id) {TbTtsJob updateJob = tbTtsJobMapper.selectById(id);return updateJob;}/*** @description: 删除定时任务* @create: 2025/01/10 14:07* @param:* @return:*/@Overridepublic 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@Overridepublic 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 实现动态定时任务 简单实现 , 有需要的可以点赞 收藏哦