Bootstrap

Quartz 业务添加、删除、修改定时任务,订单到期失效场景

将quartz交给spring管理,在activemq队列中添加定时任务,设置任务销毁时间

添加任务后在指定时间后执行一次,自动销毁任务

Maven依赖

<!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz -->
        <dependency>
            <groupId>org.quartz-scheduler</groupId>
            <artifactId>quartz</artifactId>
            <version>2.3.0</version>
        </dependency>

配置文件xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   

    <!-- lazy-init="true" 容器启动时不执行 -->
    <bean id="schedulerFactoryBean" lazy-init="true" autowire="no"
          class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
    </bean>

    <!-- 用来在业务中动态对任务容器进行操作 -->
    <bean id="quartzManager" class="com.realfake.manager.bussiness.quarzt.QuartzManager" lazy-init="false" init-method="startJobs" >
        <!--这个对象一定要注入,这样类才能进行管理,还有在类型要用get set方法,不然会报错。-->
        <property name="scheduler" ref="schedulerFactoryBean" />
    </bean>
</beans>

 

执行任务的任务类TestJob

package com.realfake.manager.bussiness.quarzt.job;

import org.quartz.Job;
import org.quartz.JobExecutionContext;

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

public class TestJob implements Job {
    

    @Override
    public void execute(JobExecutionContext jobExecutionContext)  {
        System.out.println("————1"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
    }
}

消息接收类

package com.realfake.manager.bussiness.infoBiz;

import com.realfake.manager.bussiness.quarzt.QuartzManager;
import com.realfake.manager.bussiness.quarzt.job.TestJob;
import com.realfake.manager.bussiness.utils.QuartzCronDateUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;
import java.text.SimpleDateFormat;
import java.util.Date;

public class AddJob implements MessageListener {

    @Resource
    private QuartzManager quartzManager;

    @Override
    @Transactional
    public void onMessage(Message message) {
        try {
            //这里可以进行业务操作 例如注入服务等
            System.out.println("定时任务 收到一条消息:"+((TextMessage)message).getText());
            init();
        } catch (JMSException e) {
            e.printStackTrace();
        }
    }
    public void init(){
        System.out.println("————初始化任务"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        // 具体名字可以根据订单号来变化
        String jobName = "test";
        // 执行时间在3秒后
        Date cronDate = new Date(new Date().getTime()+3000);

        // 销毁时间在执行1秒后
        quartzManager.addJob(jobName,jobName,jobName,jobName, TestJob.class, QuartzCronDateUtils.getCron(cronDate),new Date(cronDate.getTime()+1000));


    }
}

任务管理类QuartzManager

package com.realfake.manager.bussiness.quarzt;

import org.quartz.*;

import java.util.Date;

public class QuartzManager {

    private Scheduler scheduler;

    public Scheduler getScheduler() {
        return scheduler;
    }

    public void setScheduler(Scheduler scheduler) {
        this.scheduler = scheduler;
    }

    /**
     * 功能: 添加一个定时任务
     * @param jobName 任务名
     * @param jobGroupName  任务组名
     * @param triggerName 触发器名
     * @param triggerGroupName 触发器组名
     * @param jobClass  任务的类类型  eg:TimedMassJob.class
     * @param cron   时间设置 表达式,参考quartz说明文档
     */
    public void addJob(String jobName, String jobGroupName, String triggerName, String triggerGroupName, Class jobClass, String cron, Date endDate, Object...objects) {
        try {
            // 任务名,任务组,任务执行类
            JobDetail jobDetail= JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroupName).build();
            // 触发器
            if(objects!=null){
                for (int i = 0; i < objects.length; i++) {
                    //该数据可以通过Job中的JobDataMap dataMap = context.getJobDetail().getJobDataMap();来进行参数传递值
                    jobDetail.getJobDataMap().put("data"+(i+1), objects[i]);
                }
            }
            TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
            // 触发器名,触发器组
            triggerBuilder.withIdentity(triggerName,triggerGroupName);
            triggerBuilder.startNow();
            // 如果有设置终止时间
            if(endDate!=null)
                triggerBuilder.endAt(endDate);
            // 触发器时间设定
            triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
            // 创建Trigger对象
            CronTrigger trigger = (CronTrigger) triggerBuilder.build();
            // 调度容器设置JobDetail和Trigger
            scheduler.scheduleJob(jobDetail, trigger);
            // 启动
            /*if (!scheduler.isShutdown()) {
                scheduler.start();
            }*/
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 功能:修改一个任务的触发时间
     * @param jobName
     * @param jobGroupName
     * @param triggerName 触发器名
     * @param triggerGroupName 触发器组名
     * @param cron   时间设置,参考quartz说明文档
     */
    public void modifyJobTime(String jobName, String jobGroupName, String triggerName, String triggerGroupName, String cron) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(cron)) {
                // 触发器
                TriggerBuilder<Trigger> triggerBuilder = TriggerBuilder.newTrigger();
                // 触发器名,触发器组
                triggerBuilder.withIdentity(triggerName, triggerGroupName);
                triggerBuilder.startNow();
                // 触发器时间设定
                triggerBuilder.withSchedule(CronScheduleBuilder.cronSchedule(cron));
                // 创建Trigger对象
                trigger = (CronTrigger) triggerBuilder.build();
                // 方式一 :修改一个任务的触发时间
                scheduler.rescheduleJob(triggerKey, trigger);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 功能: 移除一个任务
     * @param jobName
     * @param jobGroupName
     * @param triggerName
     * @param triggerGroupName
     */
    public void removeJob(String jobName, String jobGroupName,String triggerName, String triggerGroupName) {
        try {
            TriggerKey triggerKey = TriggerKey.triggerKey(triggerName,triggerGroupName);
            // 停止触发器
            scheduler.pauseTrigger(triggerKey);
            // 移除触发器
            scheduler.unscheduleJob(triggerKey);
            // 删除任务
            scheduler.deleteJob(JobKey.jobKey(jobName,jobGroupName));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     *
     * 功能:启动所有定时任务
     */
    public void startJobs() {
        try {
            scheduler.start();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 功能:关闭所有定时任务
     */
    public void shutdownJobs() {
        try {
            if (!scheduler.isShutdown()) {
                scheduler.shutdown();
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

启动spring容器之后,发送消息到消息队列

任务触发为初始化任务3秒后,再发送消息因为原任务在触发任务后1秒后销毁,不会出现任务已经存在的错误。

;