Spring-boot整合Quartz,3、动态配置定时任务

通过动态添加JobDetail实例到Scheduler中,实现可配置动态式的定时任务作业
首先实现Job接口的 Myjob,通过包全名(com.example.demo.job.MyJob1),利用反射得到Clazz。
设置JobDetail的名字和组

  Class jobClass = Class.forName(job);
            // 创建jobDetail实例,绑定Job实现类
        // 指明job的名称,所在组的名称,以及绑定job类
        JobDetail jobDetail = JobBuilder.newJob(jobClass/*MyJob1.class*/) .withIdentity(jobId, group).build();//设置Job的名字和组

再配置CronTrigger参数,触发器规则,添加名字和组。

      //  corn表达式  每2秒执行一次
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time/*"0/2 * * * * ?"*/);

        //设置定时任务的时间触发规则
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(jobId,group) .withSchedule(scheduleBuilder).build();

最后将把作业和触发器注册到任务调度中
具体代码

@Component
public class MyScheduler  {
    @Autowired
    private  Scheduler scheduler;


    public void scheduleJobs() throws SchedulerException {
//        startJob();
    }

    public void startJob(String time,String group,String jobId,String job){

        try {
            Class jobClass = Class.forName(job);
            // 创建jobDetail实例,绑定Job实现类
            // 指明job的名称,所在组的名称,以及绑定job类
            JobDetail jobDetail = JobBuilder.newJob(jobClass/*MyJob1.class*/) .withIdentity(jobId, group).build();//设置Job的名字和组
//            JobDetail jobDetail = JobBuilder.newJob(jobClass/*MyJob1.class*/) .withIdentity(jobId, group).usingJobData("name","我的名字").build();//设置Job的名字和组
            jobDetail.getJobDataMap().put("name","MyName");//动态添加数据

            //  corn表达式  每2秒执行一次
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time/*"0/2 * * * * ?"*/);

        //设置定时任务的时间触发规则
        CronTrigger cronTrigger = TriggerBuilder.newTrigger().withIdentity(jobId,group) .withSchedule(scheduleBuilder).build();


        // 把作业和触发器注册到任务调度中
        scheduler.scheduleJob(jobDetail,cronTrigger);
/*
        // 启动调度
        scheduler.start();

            Thread.sleep(30000);

        // 停止调度
        scheduler.shutdown();*/
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /***
     * 修改定时任务时间
     * @param triggerName
     * @param triggerGroupName
     * @param time
     */
    public  void  modifyJobTime(String triggerName,String triggerGroupName, String time) {
        try {
            TriggerKey triggerKey = new TriggerKey(triggerName, triggerGroupName);
            CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
            if (trigger == null) {
                return;
            }
            System.out.println(scheduler.getTriggerState(triggerKey));
            String oldTime = trigger.getCronExpression();
            if (!oldTime.equalsIgnoreCase(time)) {  // Trigger已存在,那么更新相应的定时设置
                CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(time);//设置一个新的定时时间

                // 按新的cronExpression表达式重新构建trigger
                CronTrigger cronTrigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();

                // 按新的trigger重新设置job执行
                scheduler.rescheduleJob(triggerKey, cronTrigger);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /****
     * 暂停一个任务
     * @param triggerName
     * @param triggerGroupName
     */
    public void pauseJob(String triggerName,String triggerGroupName){
        try {
            JobKey jobKey = new JobKey(triggerName, triggerGroupName);
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (jobDetail==null){
                return;
            }
            scheduler.pauseJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
    /****
     * 删除一个任务
     * @param triggerName
     * @param triggerGroupName
     */
    public void deleteJob(String triggerName,String triggerGroupName){
        try {
            JobKey jobKey = new JobKey(triggerName, triggerGroupName);
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (jobDetail==null){
                return;
            }
            scheduler.deleteJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
    /****
     * 恢复一个任务
     * @param triggerName
     * @param triggerGroupName
     */
    public void resumeJob(String triggerName,String triggerGroupName){
        try {
            JobKey jobKey = new JobKey(triggerName, triggerGroupName);
            JobDetail jobDetail = scheduler.getJobDetail(jobKey);
            if (jobDetail==null){
                return;
            }
            scheduler.resumeJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }

    /***
     * 开始定时任务
     */
    public void startAllJob(){
        try {
            scheduler.start();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
    /***
     * 立即执行定时任务
     */
    public void doJob(String triggerName,String triggerGroupName){
        try {
            JobKey jobKey = JobKey.jobKey(triggerName, triggerGroupName);
            scheduler.triggerJob(jobKey);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
    public void shutdown(){
        try {
            scheduler.shutdown();
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

测试类

@Autowired
    private MyScheduler myScheduler ;


    @Test
    public void TestQuartz(){
        try {
            myScheduler.startJob("0/5 * * * * ? ","gropu1","job1","com.example.demo.job.MyJob1");
            myScheduler.startAllJob();
            Thread.sleep(   30000);
            myScheduler.modifyJobTime("job1","gropu1","0/2 * * * * ? ");
            Thread.sleep(   30000);
            myScheduler.pauseJob("job1","gropu1");
            Thread.sleep(   10000);
            myScheduler.resumeJob("job1","gropu1");
            Thread.sleep(   10000);
            myScheduler.doJob("job1","gropu1");
            myScheduler.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

暂停,删除,恢复通过JobDetail设置的名字和组,生成JobKey,从scheduler中获取JobDetail,再操作。

修改Job触发时间规则的,首先获取触发器的名字和组,再把新的触发器规则重新设置job执行
scheduler.rescheduleJob(triggerKey, cronTrigger);

关于线程并发问题
https://my.oschina.net/blueskyer/blog/325812
参考该文章

在Job的实现类上加@DisallowConcurrentExecution的注释
@DisallowConcurrentExecution 禁止并发执行多个相同定义的JobDetail, 这个注解是加在Job类上的, 但意思并不是不能同时执行多个Job, 而是不能并发执行同一个Job Definition(由JobDetail定义), 但是可以同时执行多个不同的JobDetail, 举例说明,我们有一个Job类,叫做SayHelloJob, 并在这个Job上加了这个注解, 然后在这个Job上定义了很多个JobDetail, 如sayHelloToJoeJobDetail, sayHelloToMikeJobDetail, 那么当scheduler启动时, 不会并发执行多个sayHelloToJoeJobDetail或者sayHelloToMikeJobDetail, 但可以同时执行sayHelloToJoeJobDetail跟sayHelloToMikeJobDetail。

@PersistJobDataAfterExecution 同样, 也是加在Job上,表示当正常执行完Job后, JobDataMap中的数据应该被改动, 以被下一次调用时用。当使用@PersistJobDataAfterExecution 注解时, 为了避免并发时, 存储数据造成混乱, 强烈建议把@DisallowConcurrentExecution注解也加上。

JobDataMap,它是JobDetail的一个属性。JobDataMap是Map接口的一个实现,并且它有一些便利的方法来储存和检索基本类型数据。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值