Quartz定时任务框架指定当前时间多久后执行

1.想法

       quartz框架采用的cron表达式必须是每天或者每几小时按照的是整体时间走的而非已当前时间做开始时间往后执行的,

      例如40分钟未支付取消订单或30分钟无回应判断其离线等等这种场景下如果想用quartz定时调度框架成了一个难题.

    虽然cron本身并不支持指定开始时间往后的某个规律执行但是我们可以换个角度去思考这个问题.

   我们首先设置一下它下次执行的时间等他再执行试我们则更改一下他下次执行的时间.话不多说上代码

2.POM导入

       由于我们的工具类使用的hutool工具类,我这里是导入的hutool的全部工具类,大家可以根据需求自行导入

       <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.7.3</version>
        </dependency>

3.corn工具类

        用我们编写的工具类生成你要执行的cron表达式 还可以再进行抽取公共地方再进行化简,我这里就不做了有有需要的自己化简抽取公共方法出来即可

public class CronUtilZ {

    /**
     *构建Cron表达式 举例: 当前时间开始每3天执行一次需传参 new Date(),3,1  
     *                    当前时间开始每5个月执行一次需传参 new Date(),5,2
     * @param  date 开始时间
     * @param  count 数量
     * @param  type 类型:0->小时 type 1->天 type 2->周  type 3->月 type 4->季度 type 5->年 6->分钟
     * @return String
     */
    public static String createCronExpression(Date date,Integer count,Integer type){
        if (count==0){
            throw new RuntimeException("错误数量填写");
        }
      
        StringBuffer cronExp = new StringBuffer("");
        //如果为小时
        if (type ==0){

            //小时
            int hour = DateUtil.hour(date,true);
            //分钟
            int minute = DateUtil.minute(date);
            //秒
            int second = DateUtil.second(date);
            //让小时部分去加一下几个小时以后执行
            hour=hour+count;
            if (hour>24){
                //大于24考虑大于多少个24
                int b=hour/24;
                //偏移大于几个24就偏移几天
                DateTime dateTime = DateUtil.offsetDay(date, b);
                //然后小时去剪去大于的24
                hour=hour-b*24;
                //获取日
                int day = DateUtil.dayOfMonth(dateTime);
                //获取月
                int month = DateUtil.month(dateTime);
                //月份需加1因为 糊涂工具类是从0开始算的
                month=month+1;
                //获取年份
                int year = DateUtil.year(dateTime);
                cronExp.append(second).append(" ");
                cronExp.append(minute).append(" ");
                cronExp.append(hour).append(" ");
                cronExp.append(day).append(" ");
                cronExp.append(month).append(" ");
                cronExp.append("? ");
                cronExp.append(year).append("-").append(year);
            }else {
                cronExp.append(second).append(" ");
                cronExp.append(minute).append(" ");
                cronExp.append(hour).append(" ");
                cronExp.append("* ");
                cronExp.append("* ");
                cronExp.append("? ");
                cronExp.append("*");
                return cronExp.toString();
            }
        }

        //如果为天
        if (type ==1){
            //小时
            int hour = DateUtil.hour(date,true);
            //分钟
            int minute = DateUtil.minute(date);
            //秒
            int second = DateUtil.second(date);
            //偏移count天
            DateTime dateTime = DateUtil.offsetDay(new Date(), count);
            //获取日
            int day = DateUtil.dayOfMonth(dateTime);
            //获取月
            int month = DateUtil.month(dateTime);
            //月份需加1因为 糊涂工具类是从0开始算的
            month=month+1;
            //获取年份
            int year = DateUtil.year(dateTime);
            cronExp.append(second).append(" ");
            cronExp.append(minute).append(" ");
            cronExp.append(hour).append(" ");
            cronExp.append(day).append(" ");
            cronExp.append(month).append(" ");
            cronExp.append("? ");
            cronExp.append(year).append("-").append(year);
            return cronExp.toString();
        }

        //如果为周
        if (type ==2){
            //小时
            int hour = DateUtil.hour(date,true);
            //分钟
            int minute = DateUtil.minute(date);
            //秒
            int second = DateUtil.second(date);
            //偏移个count*7天
            DateTime dateTime = DateUtil.offsetDay(new Date(), count*7);
            //获取日
            int day = DateUtil.dayOfMonth(dateTime);
            //获取月
            int month = DateUtil.month(dateTime);
            //月份需加1因为 糊涂工具类是从0开始算的
            month=month+1;
            //获取年份
            int year = DateUtil.year(dateTime);
            cronExp.append(second).append(" ");
            cronExp.append(minute).append(" ");
            cronExp.append(hour).append(" ");
            cronExp.append(day).append(" ");
            cronExp.append(month).append(" ");
            cronExp.append("? ");
            cronExp.append(year).append("-").append(year);
            return cronExp.toString();
        }

        //如果为月
        if (type ==3){

            //小时
            int hour = DateUtil.hour(date,true);
            //分钟
            int minute = DateUtil.minute(date);
            //秒
            int second = DateUtil.second(date);
            //偏移个count*30天
            DateTime dateTime = DateUtil.offsetDay(new Date(), count*30);
            //获取日
            int day = DateUtil.dayOfMonth(dateTime);
            //获取月
            int month = DateUtil.month(dateTime);
            //月份需加1因为 糊涂工具类是从0开始算的
            month=month+1;
            //获取年份
            int year = DateUtil.year(dateTime);
            cronExp.append(second).append(" ");
            cronExp.append(minute).append(" ");
            cronExp.append(hour).append(" ");
            cronExp.append(day).append(" ");
            cronExp.append(month).append(" ");
            cronExp.append("? ");
            cronExp.append(year).append("-").append(year);
            return cronExp.toString();
        }

        //如果为季度
        if (type ==4){

            //小时
            int hour = DateUtil.hour(date,true);
            //分钟
            int minute = DateUtil.minute(date);
            //秒
            int second = DateUtil.second(date);
            //偏移个count*90天
            DateTime dateTime = DateUtil.offsetDay(new Date(), count*90);
            //获取日
            int day = DateUtil.dayOfMonth(dateTime);
            //获取月
            int month = DateUtil.month(dateTime);
            //月份需加1因为 糊涂工具类是从0开始算的
            month=month+1;
            //获取年份
            int year = DateUtil.year(dateTime);
            cronExp.append(second).append(" ");
            cronExp.append(minute).append(" ");
            cronExp.append(hour).append(" ");
            cronExp.append(day).append(" ");
            cronExp.append(month).append(" ");
            cronExp.append("? ");
            cronExp.append(year).append("-").append(year);
            return cronExp.toString();
        }


        //如果为年
        if (type ==5){

            //小时
            int hour = DateUtil.hour(date,true);
            //分钟
            int minute = DateUtil.minute(date);
            //秒
            int second = DateUtil.second(date);
            //获取日
            int day = DateUtil.dayOfMonth(date);
            //获取月
            int month = DateUtil.month(date);
            //月份需加1因为 糊涂工具类是从0开始算的
            month=month+1;
            //获取年份直接+count就行
            int year = DateUtil.year(date)+count;

            cronExp.append(second).append(" ");
            cronExp.append(minute).append(" ");
            cronExp.append(hour).append(" ");
            cronExp.append(day).append(" ");
            cronExp.append(month).append(" ");
            cronExp.append("? ");
            cronExp.append(year).append("-").append(year);
            return cronExp.toString();
        }

        //如果为分钟
        if (type ==6){


            //小时
            int hour = DateUtil.hour(date,true);
            //分钟
            int minute = DateUtil.minute(date);
            //秒
            int second = DateUtil.second(date);
            //让小时部分去加一下几个小时以后执行
            minute=minute+count;
            if (minute>60){
                //大于24考虑大于多少个24
                int b=minute/60;
                minute=minute-b*60;
                if (hour+b>24){
                    int c=hour/24;
                    //然后小时去剪去大于的24
                    hour=hour-c*24;
                    //偏移大于几个24就偏移几天
                    date = DateUtil.offsetDay(date, c);
                    //获取日
                    int day = DateUtil.dayOfMonth(date);
                    //获取月
                    int month = DateUtil.month(date);
                    //月份需加1因为 糊涂工具类是从0开始算的
                    month=month+1;
                    //获取年份
                    int year = DateUtil.year(date);
                    cronExp.append(second).append(" ");
                    cronExp.append(minute).append(" ");
                    cronExp.append(hour).append(" ");
                    cronExp.append(day).append(" ");
                    cronExp.append(month).append(" ");
                    cronExp.append("? ");
                    cronExp.append(year).append("-").append(year);

                }else {
                    //获取日
                    int day = DateUtil.dayOfMonth(date);
                    //获取月
                    int month = DateUtil.month(date);
                    //月份需加1因为 糊涂工具类是从0开始算的
                    month=month+1;
                    //获取年份
                    int year = DateUtil.year(date);
                    cronExp.append(second).append(" ");
                    cronExp.append(minute).append(" ");
                    cronExp.append(hour).append(" ");
                    cronExp.append(day).append(" ");
                    cronExp.append(month).append(" ");
                    cronExp.append("? ");
                    cronExp.append(year).append("-").append(year);
                }







            }else {
                cronExp.append(second).append(" ");
                cronExp.append(minute).append(" ");
                cronExp.append(hour).append(" ");
                cronExp.append("* ");
                cronExp.append("* ");
                cronExp.append("? ");
                cronExp.append("*");
                return cronExp.toString();
            }
        }

        return null;
    }




}

4.使用方法

       1.首先在你开始quartz调度之前用工具类生成下一次开始的cron表达式例如

 /**
     * 假装这是你的controller层的开始方法
     * @param date
     * @param count
     * @param type
     */
    public void start(Date date,Integer count, Integer type) {
         //生成对应的cron表达式然后传递给你的Quartz的开始调度的方法
        //生成的cron表达式对应的意思是 当前时间开始3个小时后执行一次
        String cronExpression = CronUtilZ.createCronExpression(new Date(), 3, 0);

    }

    2.到生成的表达式后生成下一次的表达式更新一次例如

    @Component
    public class ReplenishOrderJob implements Job {

        @Override
        public void execute(JobExecutionContext context) {
            // 获取定时任务名(定时任务时间id)
            String timingDateId = context.getJobDetail().getKey().getName();
            // 获取定时任务组名(定时任务id)
            String timingId = context.getJobDetail().getKey().getGroup();
        }
            //开始执行定时任务了
            /**
              这里都是你的任务执行的逻辑





            */
           //获取当前时间下次的3小时后的执行时间
            String corn = CronUtilZ.createCronExpression(new Date(), 3, 0)
           //更新你的cron表达式即可
            xxx.upd(timingDateId,corn)

    }

5.总结

       总结下来其实就是开始的时候生成表达式,然后等执行的时候再生成新的下次表达式更新即可

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值