spring boot 集成 quartz,实现动态控制

spring boot 集成 quartz

spring boot 自带的定时任务 schedule使用起来非常简单,但是不灵活。如果需要动态的去修改任务间隔,可以实现,但就是比较麻烦。这里记录一下quartz在spring boot 中的使用,权当抛砖引玉。

1、引入jar包
    <dependency>
        <groupId>org.quartz-scheduler</groupId>
        <artifactId>quartz</artifactId>
        <version>2.2.3</version>
        <exclusions>
            <exclusion>
                <artifactId>slf4j-api</artifactId>
                <groupId>org.slf4j</groupId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
    </dependency>
2、新建一个任务类,实现Job接口
@DisallowConcurrentExecution
@Component
public class OneJob implements Job{
    private String name;
    private int pid;

    private Logger logger = LoggerFactory.getLogger(OneJob .class);

    public void doSomething(){
        logger.info(new Date()+"--"+name+" :启动任务");

        try {
            Thread.sleep(7000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        logger.info(pid+"任务结束");
    }

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        crawling();
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }
}

注解@DisallowConcurrentExecution表示一次只允许执行一个任务,不加这个注解的话,可以多任务同时运行

注意:任务类中属性比如name,pid 和其他对象类,不能通过spring boot自动注入的方式获取,如果通过@Autowired方式注入属性值,会是null值,如何注入,下一步会讲。

3、quartz任务操作类

上一步提到的如何注入job类参数,需要通过JobDetail.getJobDataMap()方法注入。

@Service
public class QuartzService {
    private static  Scheduler scheduler=getScheduler();
    private static String JOB_GROUP_NAME = "OJ_JOBGROUP_NAME";
    private static String TRIGGER_GROUP_NAME = "OJ_TRIGGERGROUP_NAME";
    private static Map<String,TriggerKey> TRIGGERKEYMAP = new HashMap<>();
    private static Map<String,JobKey> JOBKEYMAP = new HashMap<>();

    @Value("${task.pid}")
    private int pid;
    /**
     * 创建一个调度对象
     * @return
     * @throws SchedulerException
     */
    private static Scheduler getScheduler() {
        SchedulerFactory sf = new StdSchedulerFactory();
        Scheduler scheduler=null;
        try {
            scheduler = sf.getScheduler();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return scheduler;
    }

    /**
     * 添加一个任务
     * @param jobName
     * @param task
     * @param cron
     * @return
     */
    public Map<String,String> addJob(String jobName,Class task,String cron){
        Map<String,String> map = new HashMap<>();
        try {

            Trigger trigger = newTrigger()
                    .withIdentity(jobName,TRIGGER_GROUP_NAME)
                    .startNow()
                    .withSchedule(cronSchedule(cron))
                    .build();
            TRIGGERKEYMAP.put(jobName,trigger.getKey());

            JobDetail jobDetail = newJob()
                    .ofType(task)
                    .withIdentity(jobName,JOB_GROUP_NAME)
                    .build();
            JOBKEYMAP.put(jobName,jobDetail.getKey());
            jobDetail.getJobDataMap().put("name",jobName);
            jobDetail.getJobDataMap().put("pid",pid);

            try {
                Date date = scheduler.scheduleJob(jobDetail,trigger);
            }catch (ObjectAlreadyExistsException e){
                map.put("info","Job already exists");
                map.put("status","0");
                return map;
            }


            if (!scheduler.isShutdown()) {
                scheduler.start();
            }

        } catch (SchedulerException e) {
            throw new RuntimeException(e);
        }
        map.put("info","start job success");
        map.put("status","1");
        return map;
    }

    /**
     * 修改触发器时间间隔
     * @param jobName
     * @param cron
     * @throws SchedulerException
     */
    public Map<String,String> modifyJobTime(String jobName, String cron){
        System.out.println("modifyJobTime");
        Trigger trigger = newTrigger()
                .withIdentity(jobName,TRIGGER_GROUP_NAME)
                .startNow()
                .withSchedule(cronSchedule(cron))
                .build();
        Map<String,String> map = new HashMap<>();
        try {
            scheduler.rescheduleJob(trigger.getKey(),trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
            map.put("info","modify failed");
            map.put("status","0");
            return map;
        }
        map.put("info","success");
        map.put("status","1");
        return map;
    }

    /**
     * * @param jobName
     * 停止使用相关的触发器
     */
    public Map<String,String> pauseTrigger(String jobName) {
        System.out.println("pause trigger");
        Map<String,String> map = new HashMap<>();
        try {
            scheduler.pauseTrigger(TRIGGERKEYMAP.get(jobName));
        } catch (SchedulerException e) {
            e.printStackTrace();
            map.put("info","pause failed");
            map.put("status","0");
            return map;
        }
        map.put("info","success");
        map.put("status","1");
        return map;
    }
    /**
     * 恢复使用相关的触发器
     * @param jobName
     */
    public  Map<String,String> resumeTrigger(String  jobName) {
        System.out.println("resume trigger");
        Map<String,String> map = new HashMap<>();
        try {
            scheduler.resumeTrigger(TRIGGERKEYMAP.get(jobName));
        } catch (SchedulerException e) {
            e.printStackTrace();
            map.put("info","resume trigger failed");
            map.put("status","0");
            return map;
        }
        map.put("info","success");
        map.put("status","1");
        return map;

    }

    /**
     * 暂停任务
     * @param jobName
     */
    public Map<String,String> pauseJob(String jobName){
        System.out.println("pause job");
        Map<String,String> map = new HashMap<>();
        try {
            scheduler.pauseJob(JOBKEYMAP.get(jobName));
        } catch (SchedulerException e) {
            e.printStackTrace();
            map.put("info","pause job failed");
            map.put("status","1");
            return map;
        }
        map.put("info","success");
        map.put("status","2");
        return map;
    }

    /**
     * 恢复任务
     * @param jobName
     */
    public Map<String,String> resumeJob(String jobName) {
        System.out.println("resume job");
        Map<String,String> map = new HashMap<>();
        try {
            scheduler.resumeJob(JOBKEYMAP.get(jobName));
        } catch (SchedulerException e) {
            e.printStackTrace();
            map.put("info","resume job failed");
            map.put("status","2");
            return map;
        }
        map.put("info","success");
        map.put("status","1");
        return map;
    }

    /**
     * 删除任务
     * @param jobName
     */
    public Map<String,String> deleteJob(String jobName) {
        System.out.println("deleteJob");
        Map<String,String> map = new HashMap<>();
        try {
            scheduler.deleteJob(JOBKEYMAP.get(jobName));
        } catch (SchedulerException e) {
            e.printStackTrace();
            map.put("info","delete job failed");
            map.put("status","0");
            return map;
        }
        map.put("info","success");
        map.put("status","1");
        return map;
    }

    /**
     * 判断是否还有在执行任务
     * @return
     */
    public boolean hasJobRunning(){
        List<JobExecutionContext> list = null;
        try {
            list = scheduler.getCurrentlyExecutingJobs();
        } catch (SchedulerException e) {
            e.printStackTrace();
            return false;
        }
        if(list.size()>0) return true;
        return false;
    }
    /**
     * 关闭调度器
     * @throws SchedulerException
     */
    public Boolean shutDownScheduler(){
        try {
            if (scheduler.isStarted()) {
                scheduler.shutdown();
                return true;
            }
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
        return false;
    }
}

以上就是基本的一些quartz操作,如果需要其他功能,自行在添加即可。
多个定时任务,新建任务类去实现Job接口。

1、一个触发器可以触发多个任务
2、多个任务按该触发器设定频率运行
3、同一组内不能有同样的任务名或者触发器名
4、触发器暂停,该触发器控制的所有任务暂停
5、如果一个任务运行时长大于任务间隔,则执行完毕该任务会继续执行下个任务,比如:任务运行7s,间隔5s,下一次任务会等待第一次执行完再继续执行
6、更改触发器执行间隔,将等待正在执行的任务执行完毕后,再使用新的执行间隔
7、如果暂停触发器,正在执行的任务会执行完毕
8、如果进行过任务触发间隔动态修改,暂停后再启动,会等到时间一致才会到正确的频率上,原因未知。

如有问题,欢迎留言讨论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值