<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      SpringBoot整合Quartz定時任務

      Quartz基本概念

      Quartz是一個任務調度框架,主要用于在特定時間觸發任務執行。?
      
      Quartz的核心概念
      ?調度器(Scheduler)?:負責任務的調度和管理,包括任務的啟動、暫停、恢復等操作。
      ?任務(Job)?:需要實現org.quartz.Job接口的execute方法,定義了任務的具體執行邏輯。
      ?觸發器(Trigger)?:定義任務執行的觸發條件,包括簡單觸發器(SimpleTrigger)和cron觸發器(CronTrigger)。
      ?任務詳情(JobDetail)?:用于定義任務的詳細信息,如任務名、組名等。
      ?任務構建器(JobBuilder)和觸發器構建器(TriggerBuilder)?:用于定義和構建任務和觸發器的實例。
      ?線程池(ThreadPool)?:用于并行調度執行每個作業,提高效率。
      ?監聽器(Listener)?:包括任務監聽器、觸發器監聽器和調度器監聽器,用于監聽任務和觸發器的狀態變化。
      Quartz的基本使用步驟
      ?創建任務類?:實現Job接口的execute方法,定義任務的執行邏輯。
      ?生成任務詳情(JobDetail)?:通過JobBuilder定義任務的詳細信息。
      ?生成觸發器(Trigger)?:通過TriggerBuilder定義任務的觸發條件,可以選擇使用簡單觸發器或cron觸發器。
      ?獲取調度器(Scheduler)?:通過SchedulerFactory創建調度器對象,并將任務和觸發器綁定在一起,啟動調度器。
      Quartz的優點和缺點
      ?優點?:支持復雜的調度需求,包括定時、重復執行、并發執行等;提供了豐富的API和工具類,易于使用和維護;支持Spring集成,方便在Spring項目中應用。
      ?缺點?:配置復雜,需要一定的學習成本;對于簡單的定時任務,使用Quartz可能會顯得過于復雜。

      整合SpringBoot

      第一步:添加依賴

      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-quartz</artifactId>
      </dependency>

      第二步:創建scheduler

      import org.quartz.Scheduler;
      import org.quartz.SchedulerException;
      import org.quartz.SchedulerFactory;
      import org.quartz.impl.StdSchedulerFactory;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      
      @Configuration
      public class QuartzConfig {
          @Bean
          public Scheduler scheduler() throws SchedulerException {
              SchedulerFactory schedulerFactoryBean new StdSchedulerFactory();
              return schedulerFactoryBean.getScheduler();
          }
      }

      第三步:創建Job

      import com.songwp.utils.DateUtil;
      import lombok.extern.slf4j.Slf4j;
      import org.quartz.Job;
      import org.quartz.JobDataMap;
      import org.quartz.JobExecutionContext;
      import org.quartz.JobExecutionException;
      import org.springframework.stereotype.Component;
      
      import java.util.Date;
      
      @Slf4j
      @Component
      public class MyJob implements Job {
          @Override
          public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
              JobDataMap jobDataMap = jobExecutionContext.getJobDetail().getJobDataMap();
              log.info("入參:{}", jobDataMap.toString());
              log.info("執行定時任務的時間:{}", DateUtil.dateToStr(new Date()));
          }
      }

      第四步:創建任務信息類

      import lombok.Data;
      
      @Data
      public class JobInfo {
          private Long jobId;
          private String cronExpression;
          private String businessId;
      }

      第五步:創建JobDetail和trigger創建包裝類

      import com.songwp.domain.quartz.JobInfo;
      import com.songwp.test.MyJob;
      import org.quartz.*;
      import java.util.Date;
      
      public class QuartzBuilder {
          public static final String RUN_CRON ="定時執行";
          public static final String RUN_ONE ="執行一次";
          private static final String JOB_NAME_PREFIX ="flow";
          public static final String TRIGGER_NAME_PREFIX ="trigger.";
      
          public static JobDetail createJobDetail(JobInfo jobInfo, String type){
              String jobKey =JOB_NAME_PREFIX + jobInfo.getJobId();
              if (RUN_ONE.equals(type)){
                  jobKey = JOB_NAME_PREFIX + new Date().getTime();
              }
      
              return JobBuilder.newJob(MyJob.class)
                      .withIdentity(jobKey,"my_group")
                      .usingJobData("businessId",jobInfo.getBusinessId())
                      .usingJobData("businessType","其他參數")
                      .storeDurably().build();
          }
      
      
          public static Trigger createTrigger(JobDetail jobDetail, JobInfo jobInfo){
              return TriggerBuilder.newTrigger()
                      .forJob(jobDetail)
                      .withIdentity(TRIGGER_NAME_PREFIX + jobInfo.getJobId(),RUN_CRON)
                      .withSchedule(CronScheduleBuilder.cronSchedule(jobInfo.getCronExpression()))
                      .build();
              }
      }

      第六步:控制層接口實現接口(執行一次、啟動定時、暫停任務)

      import com.songwp.config.quartz.QuartzBuilder;
      import com.songwp.domain.quartz.JobInfo;
      import lombok.extern.slf4j.Slf4j;
      import org.quartz.*;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.RestController;
      import javax.annotation.PostConstruct;
      
      @RestController
      @Slf4j
      public class QuartzController {
      
          @Autowired
          private Scheduler scheduler;
      
          /**
           * 定時任務執行(只執行一次)
           * @return
           */
          @GetMapping("runOne")
          public  String runOne(){
              JobInfo jobInfo = new JobInfo();
              jobInfo.setJobId(1L);
              jobInfo.setBusinessId("123");
              jobInfo.setCronExpression("0/5 * * * * ?");
              JobDetail jobDetail = QuartzBuilder.createJobDetail(jobInfo, QuartzBuilder.RUN_ONE);
              Trigger trigger = TriggerBuilder.newTrigger()
                      .forJob(jobDetail)
                      .startNow()
                      .withSchedule(SimpleScheduleBuilder.simpleSchedule().withRepeatCount(0))
                      .build();
      
              try {
                  scheduler.scheduleJob(jobDetail, trigger);
                  if (!scheduler.isStarted()) {
                      scheduler.start();
                  }
              } catch (SchedulerException e) {
                  log.error(e.getMessage());
                  return "執行失敗";
              }
              return "執行成功";
          }
      
          /**
           * 開始定時執行
           * @return 執行結果
           */
          @GetMapping("start")
          public String start() {
              try {
                  JobInfo jobInfo = new JobInfo();
                  jobInfo.setJobId(1L);
                  jobInfo.setBusinessId("123");
                  jobInfo.setCronExpression("0/5 * * * * ?");
                  TriggerKey triggerKey = new TriggerKey(QuartzBuilder.TRIGGER_NAME_PREFIX + jobInfo.getJobId(),QuartzBuilder.RUN_CRON);
                  if (scheduler.checkExists(triggerKey)) {
                      scheduler.resumeTrigger(triggerKey);
                  } else {
                      JobDetail jobDetail = QuartzBuilder.createJobDetail(jobInfo, QuartzBuilder.RUN_CRON);
                      Trigger trigger = QuartzBuilder.createTrigger(jobDetail, jobInfo);
                      scheduler.scheduleJob(jobDetail, trigger);
                      if (!scheduler.isStarted()) {
                          scheduler.start();
                      }
                  }
              } catch (SchedulerException e) {
                  log.error(e.getMessage());
                  return "執行失敗";
      
              }
              return "執行成功";
          }
      
          /**
           * 停止任務執行
           * @return 執行結果
           */
          @GetMapping("pause")
          public String pause() {
              try {
                  JobInfo jobInfo = new JobInfo();
                  jobInfo.setJobId(1L);
                  jobInfo.setBusinessId("123");
                  jobInfo.setCronExpression("0/5 * * * * ?");
                  TriggerKey triggerKey = new TriggerKey(QuartzBuilder.TRIGGER_NAME_PREFIX + jobInfo.getJobId(), QuartzBuilder.RUN_CRON);
                  if (scheduler.checkExists(triggerKey)) {
                      scheduler.pauseTrigger(triggerKey);
                  }
              } catch (SchedulerException e) {
                  log.error(e.getMessage());
                  return "執行失敗";
              }
              return "執行成功";
          }
      
          /**
           * 查詢已啟動狀態的任務,然后重新執行
           */
          @PostConstruct
          public void init(){
             log.info("查詢已啟動狀態的任務,然后重新執行");
              start();
          }
      
      }

      最后訪問接口:

      http://localhost:8080/runOne
      http://localhost:8080/start
      http://localhost:8080/pause

      正常情況下的步驟應該是這樣:

      1、創建任務時記錄到任務表job_info,此時初始狀態為0

      2、啟動任務時更新任務表狀態,更新為1

      3、如果應用關閉了,那么在下次應用啟動的時候,需要把狀態為1的任務也給啟動了,就不需要認為再去調接口啟動。

      posted @ 2024-10-30 17:11  [奮斗]  閱讀(812)  評論(2)    收藏  舉報
      主站蜘蛛池模板: 日本电影一区二区三区| 99热成人精品热久久66| 国产真实精品久久二三区| 青青青青国产免费线在线观看 | 日日噜噜大屁股熟妇| 内射无套内射国产精品视频| 中文字幕v亚洲日本在线电影 | 博客| 成人午夜伦理在线观看| 亚洲av午夜成人片| 亚洲男人av香蕉爽爽爽爽| 韩国 日本 亚洲 国产 不卡| 91麻豆亚洲国产成人久久| 国产美女久久久亚洲综合| 色爱综合激情五月激情| 俄罗斯老熟妇性爽xxxx| 精品国产高清中文字幕| 国产午夜精品福利视频| 女同精品女同系列在线观看| 性欧美大战久久久久久久| 国产激情第一区二区三区| 麻豆国产成人AV在线播放| 大足县| 韩国午夜理伦三级| 一区二区国产高清视频在线| 肥城市| 99久久国产精品无码| 亚洲国产精品久久久久秋霞| 亚洲 制服 丝袜 无码| 国产大学生自拍三级视频| 精品国产AV无码一区二区三区| 青青草无码免费一二三区| 亚洲一区久久蜜臀av| 天天躁夜夜躁av天天爽| 久久国产精品99久久蜜臀| 亚洲鸥美日韩精品久久| 美女18禁一区二区三区视频| 黄色特级片一区二区三区| 好深好湿好硬顶到了好爽| 337p西西人体大胆瓣开下部| 亚洲精品视频一二三四区|