• Spring-Task定时任务, (springboot项目, 动态设置时间) -- Demo


    SpringBoot + SpringTask + SpringDataJPA

    业务:

    用户选择 自动关闭 后, 可以选择一个时间(格式为yyyy-MM-dd hh:mm),时间到后触发定时任务,关闭或开启系统(修改状态)
    精确到秒倒计时会出错(未知), 所以就规定用户不能选秒, 业务逻辑也是可以的(不太好).

    核心代码:


    DynamicTaskController :

    
    /**
     * 定时任务接口
     *
     * @author wqkeep
     * @date 2020/6/10 14:51
     */
    @Slf4j
    @RestController
    @AllArgsConstructor
    @RequestMapping("/XXXXXX/task")
    public class DynamicTaskController extends BaseController {
    
          //BaseController 主要用于调用JSONResponse ,给JSONResponse 中的参数赋值,this.success(Object data)就是这样
          //JSONResponse 封装好的返回结果,有 是否成功success,数据data,消息提示msg,状态码status
    
        private final TaskServiceImpl taskServiceImpl;
    
        /**
         * 开启报名通道定时任务
         *
         * @param id 系统id
         * @param sysStatus 系统状态
         * @param countDownTime 倒计时时间
         * @return JSONResponse 封装好的返回结果,有 是否成功success,数据data,消息提示msg,状态码status
         * @throws OperationException 封装好的自定义异常信息
         */
        @PostMapping("/XXXXXX/startCron")
        public JSONResponse startCron(Long id, Integer sysStatus, @RequestParam("date") String countDownTime) throws OperationException {
            taskServiceImpl.startCron(id, sysStatus,countDownTime);
            return this.success(SysConst.SUCCESS);
        }
    
        /**
         * 关闭当前线程定时任务
         *
         * @return JSONResponse
         */
        @PostMapping("/XXXXXX/stopCron")
        public JSONResponse stopCron() {
            taskServiceImpl.stopCron();
            return this.success(SysConst.SUCCESS);
        }
    
        /**
         * TODO 定时任务存在问题
         *
         * 目前可以实现倒计时的功能, 但系统如果要集群就会存在问题(关闭不了当前线程, 用户可能会修改多个不同线程的定时任务).
         *
         */
    
    }
    

    TaskServiceImpl:

    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.scheduling.Trigger;
    import org.springframework.scheduling.TriggerContext;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
    import org.springframework.scheduling.support.CronTrigger;
    import org.springframework.stereotype.Service;
    import javax.transaction.Transactional;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.ScheduledFuture;
    
    /**
     * 定时任务
     *
     * @author wqkeep
     * @date 2020/6/10 17:31
     */
    @Slf4j
    @Service
    @Transactional(rollbackOn = RuntimeException.class)
    public class TaskServiceImpl implements TaskService {
    
        @Autowired
        private TaskRepository taskRepository; //(PO)实体类Task 对应的Repository
    
        @Autowired
        private ThreadPoolTaskScheduler threadPoolTaskScheduler;
    
        private ScheduledFuture<?> future;
    
        @Bean
        public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
            return new ThreadPoolTaskScheduler();
        }
    
        /**
         * 开启报名通道定时任务
         *
         * @param id 系统id
         * @param sysStatus 系统状态
         * @param countDownTime 倒计时时间
         * @throws OperationException 自定义异常信息
         */
        public void startCron(Long id, Integer sysStatus, String countDownTime) throws OperationException {
            String currentThread = Thread.currentThread().getName();
            log.info("DynamicTask 报名通道定时任务开启: 当前线程 " + currentThread);
            String strDateFormat = "yyyy-MM-dd HH:mm";
            SimpleDateFormat sd = new SimpleDateFormat(strDateFormat);
            Date countDownDate = null;
            try {
                countDownDate = sd.parse(countDownTime);
            } catch (Exception e) {
                throw new OperationException("字符串转换日期失败");
            }
            String cron = CronDateUtils.getCron(countDownDate);
          //task为自定义的定时任务实体类 我这里主要存储cron表达式和定时任务具体时间,需要定时任务的系统名字,只有一个定时任务需求,所以写死了(不好)
            Task task = new Task();
            task.setId(1L);
            task.setCron(cron);
            task.setName("XXXXX系统");
            task.setRemark("自动开启关闭");
            task.setCountDownTime(countDownDate);
            //保存 自定义的定时任务实体类task
            taskRepository.save(task);
            if (future != null) {
                future.cancel(true);
            }
            future = threadPoolTaskScheduler.schedule(new Runnable() {
                @SneakyThrows
                @Override
                public void run() {
                    
                    //业务代码, 我这里是修改系统状态为关闭或开启
    
                    stopCron();
                    log.info("DynamicTask 报名通道定时任务停止: 当前线程 " + currentThread);
                }
            }, new Trigger() {
                @Override
                public Date nextExecutionTime(TriggerContext triggerContext) {
                    return new CronTrigger(cron).nextExecutionTime(triggerContext);
                }
            });
        }
    
        /**
         * 关闭当前线程定时任务
         */
        public void stopCron() {
            if (future != null) {
                future.cancel(true);
            }
        }
    
    }
    
    

    cron表达式和日期转换工具类CronDateUtils :
    
    import com.zjxf.config.exception.custom.OperationException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    /**
     * 定时任务cron表达式与Date之间的转换
     *
     * @author wqkeep
     * @date 2020/6/10 14:51
     */
    public class CronDateUtils {
    
         //自定义cron表达式格式 可以修改
        private static final String CRON_DATE_FORMAT = "0/1 mm HH dd MM ?";
     
        /***
         * Date转换为cron表达式
         *
         * @param date 时间
         * @return cron类型的日期
         */
        public static String getCron(final Date date){
            SimpleDateFormat sdf = new SimpleDateFormat(CRON_DATE_FORMAT);
            String formatTimeStr = "";
            if (date != null) {
                formatTimeStr = sdf.format(date);
            }
            return formatTimeStr;
        }
    
        /**
         * cron表达式转换为Date
         *
         * @param cron Quartz cron的类型的日期
         * @return Date日期
         * @throws OperationException 自定义异常信息
         */
        public static Date getDate(final String cron) throws OperationException {
            if(cron == null) {
                return null;
            }
            SimpleDateFormat sdf = new SimpleDateFormat(CRON_DATE_FORMAT);
            Date date = null;
            try {
                date = sdf.parse(cron);
            } catch (Exception e) {
                throw new OperationException("转换失败");
            }
            return date;
        }
    }
    
    

    参考博客:

    https://blog.csdn.net/weixin_37591536/article/details/82150933

  • 相关阅读:
    Java 报错 -source 1.5 中不支持 diamond 运算符
    MacBook Java开发环境的配置
    MacBook 版本控制工具
    版本控制工具 Git SourceTree SSH 连接码云
    接口 请求https接口
    快递 共享电子面单
    快递 已发货订单重新打印电子面单
    SQL Server 分部分项导入后 数据的修改
    Hive数据的存储以及在centos7下进行Mysql的安装
    Hive初体验
  • 原文地址:https://www.cnblogs.com/wqkeep/p/13131432.html
Copyright © 2020-2023  润新知