<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 9754字,需瀏覽 20分鐘

           ·

          2020-08-10 21:25

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

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


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

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

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

          一、Quartz 簡介

          Quartz是一個(gè)開源的作業(yè)調(diào)度框架,它完全由Java寫成,并設(shè)計(jì)用于J2SE和J2EE應(yīng)用中。它提供了巨大的靈 活性而不犧牲簡單性。你能夠用它來為執(zhí)行一個(gè)作業(yè)而創(chuàng)建簡單的或復(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 的依賴,其余依賴請根據(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對象", 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è)測試的類 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
          ?* 測試定時(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á)式的知識這里就不一一介紹了

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

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

          3、后臺添加定時(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 對象,使用該對象開啟或停止定時(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ā)測試

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

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

          六、優(yōu)化建議

          當(dāng)我們添加了定時(shí)任務(wù)并啟動(dòng)后,重新啟動(dòng)項(xiàng)目的時(shí)候,定時(shí)任務(wù)卻不會自動(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í),就會自動(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)載請附上原文出處鏈接和本聲明。

          本文鏈接:

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



          ??? ?




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


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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  黄 色 视 频小便一区二区三 | 大鸡巴视频在线免费观看 | 亚洲国产一本 | i呦视频在线观看 | 亚洲小色网 |