1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        SpringBoot中使用Quartz管理定時(shí)任務(wù)

        共 9754字,需瀏覽 20分鐘

         ·

        2020-08-10 21:25

        點(diǎn)擊上方“ java1234?”,選擇“標(biāo)星公眾號(hào)

        優(yōu)質(zhì)文章,第一時(shí)間送達(dá)


        66套java從入門到精通實(shí)戰(zhàn)課程分享

        定時(shí)任務(wù)在系統(tǒng)中用到的地方很多,例如每晚凌晨的數(shù)據(jù)備份,每小時(shí)獲取第三方平臺(tái)的 Token 信息等等,之前我們都是在項(xiàng)目中規(guī)定這個(gè)定時(shí)任務(wù)什么時(shí)候啟動(dòng),到時(shí)間了便會(huì)自己?jiǎn)?dòng),那么我們想要停止這個(gè)定時(shí)任務(wù)的時(shí)候,就需要去改動(dòng)代碼,還得啟停服務(wù)器,這是非常不友好的事情

        直至遇見 Quartz,利用圖形界面可視化管理定時(shí)任務(wù),使得我們對(duì)定時(shí)任務(wù)的管理更加方便,快捷

        一、Quartz 簡(jiǎn)介

        Quartz是一個(gè)開源的作業(yè)調(diào)度框架,它完全由Java寫成,并設(shè)計(jì)用于J2SE和J2EE應(yīng)用中。它提供了巨大的靈 活性而不犧牲簡(jiǎn)單性。你能夠用它來為執(zhí)行一個(gè)作業(yè)而創(chuàng)建簡(jiǎn)單的或復(fù)雜的調(diào)度。它有很多特征,如:數(shù)據(jù)庫支持,集群,插件,EJB作業(yè)預(yù)構(gòu) 建,JavaMail及其它,支持cron-like表達(dá)式等等。

        二、開發(fā)前戲

        1、引入 maven 依賴



        <dependency>
        ????<groupId>org.springframework.bootgroupId>
        ????<artifactId>spring-boot-starter-webartifactId>
        dependency>

        <dependency>
        ????<groupId>org.springframework.bootgroupId>
        ????<artifactId>spring-boot-starter-quartzartifactId>
        dependency>


        這里引入了 web 的依賴,以及 Quartz 的依賴,其余依賴請(qǐng)根據(jù)需求自行引入

        2、創(chuàng)建數(shù)據(jù)表

        數(shù)據(jù)模型:

        SQL語句:

        drop?table?if?exists?sys_quartz;

        /*==============================================================*/
        /* Table: sys_quartz */
        /*==============================================================*/
        create?table?sys_quartz
        (
        ???id???????????????????bigint(20) not?null?auto_increment comment?'主鍵id',
        ???class_name varchar(32) comment?'任務(wù)類名',
        ???cron_expression varchar(32) comment?'cron表達(dá)式',
        ???param varchar(32) comment?'參數(shù)',
        ???descript varchar(11) comment?'描述',
        ???quartz_status varchar(255) comment?'啟動(dòng)狀態(tài)(0--啟動(dòng)1--停止)',
        ???create_time datetime comment?'創(chuàng)建時(shí)間',
        ???create_user bigint(20) comment?'創(chuàng)建人',
        ???status???????????????tinyint(1) default?0?comment?'狀態(tài)(0--正常1--停用)',
        ???del_flag tinyint(1) default?0?comment?'刪除狀態(tài)(0,正常,1已刪除)',
        ???primary key?(id)
        )
        type?= InnoDB;

        alter?table?sys_quartz comment?'定時(shí)任務(wù)信息表';


        三、開發(fā)進(jìn)行中

        1、創(chuàng)建實(shí)體類


        import?com.baomidou.mybatisplus.annotation.*;
        import?com.baomidou.mybatisplus.extension.activerecord.Model;
        import?com.zyxx.common.annotation.Dict;
        import?io.swagger.annotations.ApiModel;
        import?io.swagger.annotations.ApiModelProperty;
        import?lombok.Data;
        import?lombok.EqualsAndHashCode;
        import?lombok.experimental.Accessors;

        import?java.io.Serializable;

        /**
        ?*


        ?* 定時(shí)任務(wù)信息表
        ?*


        ?*
        ?* @author lizhou
        ?* @since 2020-07-21
        ?*/

        @Data
        @EqualsAndHashCode(callSuper = false)
        @Accessors(chain = true)
        @TableName("sys_quartz")
        @ApiModel(value="SysQuartz對(duì)象", description="定時(shí)任務(wù)信息表")
        public?class?SysQuartz extends?Model {

        ????@ApiModelProperty(value = "主鍵id")
        ????@TableId(value = "id", type?= IdType.AUTO)
        ????private?Long id;

        ????@ApiModelProperty(value = "任務(wù)類名")
        ????@TableField("class_name")
        ????private?String?className;

        ????@ApiModelProperty(value = "cron表達(dá)式")
        ????@TableField("cron_expression")
        ????private?String?cronExpression;

        ????@ApiModelProperty(value = "參數(shù)")
        ????@TableField("param")
        ????private?String?param;

        ????@ApiModelProperty(value = "描述")
        ????@TableField("descript")
        ????private?String?descript;

        ????@ApiModelProperty(value = "啟動(dòng)狀態(tài)(0--啟動(dòng)1--停止)")
        ????@TableField("quartz_status")
        ????private?Integer quartzStatus;

        ????@ApiModelProperty(value = "狀態(tài)(0--正常1--停用)")
        ????@TableField("status")
        ????private?Integer status;

        ????@ApiModelProperty(value = "刪除狀態(tài)(0--未刪除1--已刪除)")
        ????@TableField("del_flag")
        ????@TableLogic
        ????private?Integer delFlag;

        ????@ApiModelProperty(value = "創(chuàng)建者")
        ????@TableField("create_user")
        ????private?Long createUser;

        ????@ApiModelProperty(value = "創(chuàng)建時(shí)間")
        ????@TableField("create_time")
        ????private?String?createTime;

        ????@Override
        ????protected?Serializable pkVal() {
        ????????return?this.id;
        ????}
        }


        2、實(shí)現(xiàn)定時(shí)任務(wù)的 CRUD

        下面我們就要完成定時(shí)任務(wù)的 新增、修改、刪除、啟停 等基本操作了,由于不是很復(fù)雜,這里的代碼就不貼出來了,貼幾張圖吧

        列表頁:

        新增頁:

        四、定時(shí)任務(wù)

        1、定時(shí)任務(wù)類

        我們把定時(shí)任務(wù)都放在 job 包下面,一個(gè)定時(shí)任務(wù)就是一個(gè)文件,寫一個(gè)測(cè)試的類 TestJob.java

        import?com.zyxx.common.utils.DateUtils;
        import?lombok.extern.slf4j.Slf4j;
        import?org.quartz.Job;
        import?org.quartz.JobExecutionContext;
        import?org.quartz.JobExecutionException;

        /**
        ?* @ClassName TestJob
        ?* 測(cè)試定時(shí)任務(wù)
        ?* @Author Lizhou
        ?* @Date 2020-07-21 10:58:58
        ?**/

        @Slf4j
        public class TestJob implements Job {

        ????@Override
        ????public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        ????????System.out.println("定時(shí)任務(wù)啟動(dòng):" + DateUtils.getYmdHms());
        ????}
        }


        TestJob 這個(gè)類實(shí)現(xiàn)了 Job 接口,實(shí)現(xiàn)了 execute 方法,這里還可以接收參數(shù)

        這個(gè)文件在 com.zyxx.sbm.job 包下面,那么在頁面新增定時(shí)任務(wù)的時(shí)候,就需要填寫任務(wù)類名為:com.zyxx.sbm.job.TestJob

        cron 表達(dá)式的知識(shí)這里就不一一介紹了

        2、頁面添加定時(shí)任務(wù)

        那么我們的任務(wù)類名就是:com.zyxx.sbm.job.TestJob
        cron 表達(dá)式:*/2 * * * * ?,表示兩秒鐘執(zhí)行一次
        參數(shù):我們沒有傳入?yún)?shù)

        3、后臺(tái)添加定時(shí)任務(wù)


        package?com.zyxx.sbm.service.impl;

        import?com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
        import?com.baomidou.mybatisplus.core.metadata.IPage;
        import?com.baomidou.mybatisplus.extension.plugins.pagination.Page;
        import?com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
        import?com.zyxx.common.shiro.SingletonLoginUtils;
        import?com.zyxx.common.utils.DateUtils;
        import?com.zyxx.common.utils.LayTableResult;
        import?com.zyxx.common.utils.ResponseResult;
        import?com.zyxx.sbm.entity.SysQuartz;
        import?com.zyxx.sbm.mapper.SysQuartzMapper;
        import?com.zyxx.sbm.service.SysQuartzService;
        import?lombok.extern.slf4j.Slf4j;
        import?org.apache.commons.lang3.StringUtils;
        import?org.quartz.*;
        import?org.springframework.beans.factory.annotation.Autowired;
        import?org.springframework.stereotype.Service;

        import?java.util.List;

        /**
        ?*


        ?* 定時(shí)任務(wù)信息表 服務(wù)實(shí)現(xiàn)類
        ?*


        ?*
        ?* @author?lizhou
        ?* @since?2020-07-21
        ?*/

        @Slf4j
        @Service
        public?class?SysQuartzServiceImpl?extends?ServiceImpl<SysQuartzMapper, SysQuartz> implements?SysQuartzService?{

        ????@Autowired
        ????private?Scheduler scheduler;

        ??/**
        ??* 添加定時(shí)任務(wù)
        ??*/

        ????@Override
        ????public?ResponseResult add(SysQuartz sysQuartz)?{
        ????????QueryWrapper queryWrapper = new?QueryWrapper<>();
        ????????queryWrapper.eq("class_name", sysQuartz.getClassName());
        ????????List sysQuartzList = list(queryWrapper);
        ????????if?(null?!= sysQuartzList && !sysQuartzList.isEmpty()) {
        ????????????return?ResponseResult.getInstance().error("該任務(wù)類名已經(jīng)存在");
        ????????}
        ????????sysQuartz.setCreateTime(DateUtils.getYmdHms());
        ????????sysQuartz.setCreateUser(SingletonLoginUtils.getUserId());
        ????????save(sysQuartz);
        ????????// 啟動(dòng)
        ????????if?(0?== sysQuartz.getQuartzStatus()) {
        ????????????this.schedulerAdd(sysQuartz.getClassName().trim(), sysQuartz.getCronExpression().trim(), sysQuartz.getParam());
        ????????}
        ????????return?ResponseResult.getInstance().success();
        ????}

        ????/**
        ?????* 添加定時(shí)任務(wù)
        ?????*
        ?????* @param?className
        ?????* @param?cronExpression
        ?????* @param?param
        ?????*/

        ????@Override
        ????public?void?schedulerAdd(String className, String cronExpression, String param)?{
        ????????try?{
        ????????????// 啟動(dòng)調(diào)度器
        ????????????scheduler.start();
        ????????????// 構(gòu)建job信息
        ????????????JobDetail jobDetail = JobBuilder.newJob(getClass(className).getClass()).withIdentity(className).usingJobData("param", param).build();
        ????????????// 表達(dá)式調(diào)度構(gòu)建器(即任務(wù)執(zhí)行的時(shí)間)
        ????????????CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
        ????????????// 按新的cronExpression表達(dá)式構(gòu)建一個(gè)新的trigger
        ????????????CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(className).withSchedule(scheduleBuilder).build();
        ????????????scheduler.scheduleJob(jobDetail, trigger);
        ????????} catch?(SchedulerException e) {
        ????????????log.error(e.getMessage());
        ????????} catch?(RuntimeException e) {
        ????????????log.error(e.getMessage());
        ????????} catch?(Exception e) {
        ????????????log.error(e.getMessage());
        ????????}
        ????}

        ????/**
        ?????* 刪除定時(shí)任務(wù)
        ?????*
        ?????* @param?className
        ?????*/

        ????@Override
        ????public?void?schedulerDelete(String className)?{
        ????????try?{
        ????????????scheduler.pauseTrigger(TriggerKey.triggerKey(className));
        ????????????scheduler.unscheduleJob(TriggerKey.triggerKey(className));
        ????????????scheduler.deleteJob(JobKey.jobKey(className));
        ????????} catch?(Exception e) {
        ????????????log.error(e.getMessage(), e);
        ????????}
        ????}

        ????private?static?Job getClass(String className)?throws?Exception {
        ????????Class class1 = Class.forName(className);
        ????????return?(Job) class1.newInstance();
        ????}
        }


        需要注入 Scheduler 對(duì)象,使用該對(duì)象開啟或停止定時(shí)任務(wù)

        在啟動(dòng)定時(shí)任務(wù)之前,我們應(yīng)先刪除該任務(wù)類名開啟的定時(shí)任務(wù),防止該任務(wù)類名已經(jīng)添加過了

        // 刪除定時(shí)任務(wù)
        schedulerDelete(sysQuartz.getClassName().trim());
        // 添加定時(shí)任務(wù)
        schedulerAdd(sysQuartz.getClassName().trim(), sysQuartz.getCronExpression().trim(), sysQuartz.getParam());


        添加定時(shí)任務(wù),傳入任務(wù)類名,cron 表達(dá)式,參數(shù)

        停止定時(shí)任務(wù),只需要:

        scheduler.pauseJob(JobKey.jobKey(sysQuartz.getClassName().trim()));


        根據(jù)任務(wù)類名,停止定時(shí)任務(wù)即可

        五、開發(fā)測(cè)試

        啟動(dòng)項(xiàng)目,在管理界面,開啟定時(shí)任務(wù),即可在控制臺(tái)看到打印的信息

        表示我們的定時(shí)任務(wù)已經(jīng)啟動(dòng)成功了

        六、優(yōu)化建議

        當(dāng)我們添加了定時(shí)任務(wù)并啟動(dòng)后,重新啟動(dòng)項(xiàng)目的時(shí)候,定時(shí)任務(wù)卻不會(huì)自動(dòng)啟動(dòng),這時(shí)候,我們就需要在項(xiàng)目啟動(dòng)的時(shí)候做一些事情了,也就是系統(tǒng)啟動(dòng)任務(wù)

        不清楚的同學(xué)可以復(fù)習(xí)一下之前我的博客【SpringBoot】十九、SpringBoot中實(shí)現(xiàn)啟動(dòng)任務(wù)

        import?com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
        import?com.zyxx.sbm.entity.SysQuartz;
        import?com.zyxx.sbm.service.SysQuartzService;
        import?org.springframework.beans.factory.annotation.Autowired;
        import?org.springframework.boot.CommandLineRunner;
        import?org.springframework.core.annotation.Order;
        import?org.springframework.stereotype.Component;

        import?java.util.List;

        /**
        ?* @ClassName?SystemStartTask
        ?* 項(xiàng)目啟動(dòng)任務(wù)--啟動(dòng)定時(shí)任務(wù)
        ?* @Author?Lizhou
        ?* @Date?2020-07-21 12:56:56
        ?**/

        @Component
        @Order(100)
        public?class?SystemQuartzStartTask?implements?CommandLineRunner?{

        ????@Autowired
        ????private?SysQuartzService sysQuartzService;

        ????@Override
        ????public?void?run(String... args)?throws?Exception {
        ????????// 查詢啟動(dòng)的定時(shí)任務(wù)
        ????????QueryWrapper queryWrapper = new?QueryWrapper<>();
        ????????queryWrapper.eq("status", 0);
        ????????queryWrapper.eq("quartz_status", 0);
        ????????List list = sysQuartzService.list(queryWrapper);
        ????????if?(null?!= list && !list.isEmpty()) {
        ????????????for?(SysQuartz item : list) {
        ????????????????// 刪除定時(shí)任務(wù)
        ????????????????sysQuartzService.schedulerDelete(item.getClassName().trim());
        ????????????????// 添加定時(shí)任務(wù)
        ????????????????sysQuartzService.schedulerAdd(item.getClassName().trim(), item.getCronExpression().trim(), item.getParam());
        ????????????}
        ????????}
        ????}
        }


        從數(shù)據(jù)庫查詢出啟動(dòng)的定時(shí)任務(wù),并將他們添加到定時(shí)任務(wù)啟動(dòng)中,這樣項(xiàng)目一啟動(dòng)時(shí),就會(huì)自動(dòng)啟動(dòng)我們定義的定時(shí)任務(wù)了

        最后

        任務(wù)類名的正則表達(dá)式

        /^[a-zA-Z]+(\.([a-zA-Z])+)+$/


        cron 表達(dá)式的驗(yàn)證使用正則太麻煩,可以使用 Quartz 自帶驗(yàn)證方法

        CronExpression.isValidExpression(cron)


        SpringBoot 中使用 Quartz 管理定時(shí)任務(wù)的學(xué)習(xí)就到這兒了,其實(shí)也并不難理解,相比于之前用的定時(shí)任務(wù)是不是好很多了呢,別忘了最后加上系統(tǒng)啟動(dòng)任務(wù)哦

        如您在閱讀中發(fā)現(xiàn)不足,歡迎留言?。?!


        版權(quán)聲明:本文為博主原創(chuàng)文章,遵循?CC 4.0 BY-SA?版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。

        本文鏈接:

        https://blog.csdn.net/qq_40065776/article/details/107489728



        ??? ?




        感謝點(diǎn)贊支持下哈?


        瀏覽 79
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            少妇啪啪高潮肉谢 | 男女搞黄网站 | 看看一级黄色片 | 胸太大被老板揉了一晚上视频 | 欧美黑人又粗大 | 国产一级电影在线观看 | 日韩一级免费大片 | 在线探花| a精品视频 | 又黄又爽的视频在线观看网站 |