SpringBoot 集成 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、如果进行过任务触发间隔动态修改,暂停后再启动,会等到时间一致才会到正确的频率上,原因未知。

如有问题,欢迎留言讨论

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,598评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,744评论 6 342
  • @Author Jacky Wang转载请注明出处https://www.jianshu.com/p/b8a6c8...
    明天你好向前奔跑阅读 1,460评论 0 2
  • 为政17 子曰:“由,诲汝知之乎?知之为知之,不知为不知,是知也。” 白话 夫子说:由啊,教你什么叫知呢?知道就是...
    陈尚军阅读 257评论 0 0
  • 之归来:女人的前夫在出海中失踪10年后与另一渔夫再婚,多年后失踪的前夫一副落魄的样子出现在女人面前。比起想象的三角...
    MondeDeEVA阅读 191评论 0 0