欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBoot整合Quartz實(shí)現(xiàn)動(dòng)態(tài)配置的代碼示例

 更新時(shí)間:2023年07月20日 08:30:52   作者:失敗的面  
這篇文章將介紹如何把Quartz定時(shí)任務(wù)做成接口,實(shí)現(xiàn)以下功能的動(dòng)態(tài)配置添加任務(wù),修改任務(wù),暫停任務(wù),恢復(fù)任務(wù),刪除任務(wù),任務(wù)列表,任務(wù)詳情,文章通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下

Spring Boot整合Quartz

簡(jiǎn)單說下Quartz的整合,做一下準(zhǔn)備工作。

導(dǎo)入Quartz依賴

<!--Quartz定時(shí)任務(wù)-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

配置文件中增加Quartz的支持

spring:
 datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: xxx
    username: xxx
    password: xxx
  quartz:
    job-store-type: jdbc # 定時(shí)任務(wù)的數(shù)據(jù)保存到j(luò)dbc即數(shù)據(jù)庫(kù)中
    jdbc:
      # embedded:默認(rèn)
      # always:?jiǎn)?dòng)的時(shí)候初始化表,我們只在第一次啟動(dòng)的時(shí)候用它來自動(dòng)創(chuàng)建表,然后改回embedded即可,不然數(shù)據(jù)每次都會(huì)被清空
      # never:?jiǎn)?dòng)的時(shí)候不初始化表,也不知道和embedded有什么不同
      initialize-schema: embedded

第一次啟動(dòng)的時(shí)候請(qǐng)把上面的initialize-schema設(shè)置為always,這會(huì)在數(shù)據(jù)庫(kù)里面自動(dòng)建表,然后第二次啟動(dòng)時(shí)改回embedded即可。

如果不需要定時(shí)任務(wù)的持久化就可以不管。

寫一個(gè)測(cè)試用的任務(wù)類

import org.quartz.JobExecutionException;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
@Component
public class QuartzTestJob extends QuartzJobBean {
    @Override
    protected void executeInternal(org.quartz.JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("Quartz Test Job");
    }
}

為這個(gè)任務(wù)類寫一個(gè)配置類

import org.quartz.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class QuartzTestJobConfig {
    @Bean
    public JobDetail quartzTestJobDetail() {
        return JobBuilder.newJob(QuartzTestJob.class)
                .withIdentity(QuartzTestJob.class.getSimpleName())
                .storeDurably()
                .usingJobData("data", "test")
                .build();
    }
    @Bean
    public Trigger quartzTestJobTrigger() {
        // 0/1 * * * * ?
        return TriggerBuilder.newTrigger()
                .forJob(QuartzTestJob.class.getSimpleName())
                .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
                .build();
    }
}

結(jié)論

以上是使用Quartz寫一個(gè)定時(shí)任務(wù)的步驟,很簡(jiǎn)單,問題是配置寫死了,沒有辦法動(dòng)態(tài)調(diào)整,所以我們開始寫接口,把上面這個(gè)任務(wù)配置類去掉。

定時(shí)任務(wù)動(dòng)態(tài)配置實(shí)現(xiàn)

我們還是用上面的任務(wù)類QuartzTestJob做測(cè)試,這里再說明一次,我們需要有一個(gè)任務(wù)類作為基礎(chǔ),本文的目的只是去掉上面的QuartzTestJobConfig。

剩下的內(nèi)容沒有什么需要多說明的,我直接貼代碼了。

業(yè)務(wù)層

public interface QuartzService {
    /**
     * 添加定時(shí)任務(wù)
     */
    void addJob(QuartzCreateParam param) throws SchedulerException;
    /**
     * 修改定時(shí)任務(wù)
     */
    void updateJob(QuartzUpdateParam param) throws SchedulerException;
    /**
     * 暫停定時(shí)任務(wù)
     */
    void pauseJob(QuartzDetailParam param) throws SchedulerException;
    /**
     * 恢復(fù)定時(shí)任務(wù)
     */
    void resumeJob(QuartzDetailParam param) throws SchedulerException;
    /**
     * 刪除定時(shí)任務(wù)
     */
    void deleteJob(QuartzDetailParam param) throws SchedulerException;
    /**
     * 定時(shí)任務(wù)列表
     * @return
     */
    List<QuartzJobDetailDto> jobList() throws SchedulerException;
    /**
     * 定時(shí)任務(wù)詳情
     */
    QuartzJobDetailDto jobDetail(QuartzDetailParam param) throws SchedulerException;
}

業(yè)務(wù)層實(shí)現(xiàn)

@Service
public class QuartzServiceImpl implements QuartzService {
    @Autowired
    private Scheduler scheduler;
    @Autowired
    private SchedulerFactoryBean schedulerFactoryBean;
    @Override
    public void addJob(QuartzCreateParam param) throws SchedulerException {
        String clazzName = param.getJobClazz();
        String jobName = param.getJobName();
        String jobGroup = param.getJobGroup();
        String cron = param.getCron();
        String description = param.getDescription();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        checkJobExist(jobKey);
        Class<? extends Job> jobClass = null;
        try {
            jobClass = (Class<? extends Job>) Class.forName(clazzName);
        } catch (ClassNotFoundException e) {
            throw new BaseException("找不到任務(wù)類:" + clazzName);
        }
        JobDataMap jobDataMap = new JobDataMap();
        if (param.getJobDataMap() != null) {
            param.getJobDataMap().forEach(jobDataMap::put);
        }
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withIdentity(jobName, jobGroup)
                .usingJobData(jobDataMap)
                .build();
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
        String triggerId = jobKey.getGroup() + jobKey.getName();
        Trigger trigger = TriggerBuilder.newTrigger()
                .withSchedule(scheduleBuilder)
                .withIdentity(triggerId)
                .withDescription(description)
                .build();
        scheduler.scheduleJob(jobDetail, trigger);
        if (!scheduler.isShutdown()) {
            scheduler.start();
        }
    }
    @Override
    public void updateJob(QuartzUpdateParam param) throws SchedulerException {
        String jobName = param.getJobName();
        String jobGroup = param.getJobGroup();
        String cron = param.getCron();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        String triggerId = jobKey.getGroup() + jobKey.getName();
        checkJobExist(jobKey);
        TriggerKey triggerKey = TriggerKey.triggerKey(triggerId);
        CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron);
        TriggerBuilder<?> triggerBuilder = TriggerBuilder.newTrigger()
                .withSchedule(scheduleBuilder)
                .withIdentity(triggerId);
        Trigger trigger = triggerBuilder.build();
        scheduler.rescheduleJob(triggerKey, trigger);
    }
    @Override
    public void pauseJob(QuartzDetailParam param) throws SchedulerException {
        String jobName = param.getJobName();
        String jobGroup = param.getJobGroup();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        checkJobExist(jobKey);
        scheduler.pauseJob(jobKey);
    }
    @Override
    public void resumeJob(QuartzDetailParam param) throws SchedulerException {
        String jobName = param.getJobName();
        String jobGroup = param.getJobGroup();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        checkJobExist(jobKey);
        scheduler.resumeJob(jobKey);
    }
    @Override
    public void deleteJob(QuartzDetailParam param) throws SchedulerException {
        String jobName = param.getJobName();
        String jobGroup = param.getJobGroup();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        checkJobExist(jobKey);
        // 先暫停再刪除
        scheduler.pauseJob(jobKey);
        scheduler.deleteJob(jobKey);
    }
    @Override
    public List<QuartzJobDetailDto> jobList() throws SchedulerException {
        GroupMatcher<JobKey> matcher = GroupMatcher.anyJobGroup();
        List<QuartzJobDetailDto> jobDtoList = new ArrayList<>();
        for (JobKey jobKey : scheduler.getJobKeys(matcher)) {
            QuartzJobDetailDto jobDto = getJobDtoByJobKey(jobKey);
            jobDtoList.add(jobDto);
        }
        return jobDtoList;
    }
    @Override
    public QuartzJobDetailDto jobDetail(QuartzDetailParam param) throws SchedulerException {
        String jobName = param.getJobName();
        String jobGroup = param.getJobGroup();
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);
        return getJobDtoByJobKey(jobKey);
    }
    /*************** 私有方法 ***************/
    private void checkJobExist(JobKey jobKey) throws SchedulerException {
        if (!scheduler.checkExists(jobKey)) {
            throw new BaseException("該定時(shí)任務(wù)不存在:" + jobKey.getName());
        }
    }
    public QuartzJobDetailDto getJobDtoByJobKey(JobKey jobKey) throws SchedulerException {
        JobDetail jobDetail = scheduler.getJobDetail(jobKey);
        List<Trigger> triggerList = (List<Trigger>) scheduler.getTriggersOfJob(jobKey);
        QuartzJobDetailDto jobDto = new QuartzJobDetailDto();
        jobDto.setJobClazz(jobDetail.getJobClass().toString());
        jobDto.setJobName(jobKey.getName());
        jobDto.setJobGroup(jobKey.getGroup());
        jobDto.setJobDataMap(jobDetail.getJobDataMap());
        List<QuartzTriggerDetailDto> triggerDtoList = new ArrayList<>();
        for (Trigger trigger : triggerList) {
            QuartzTriggerDetailDto triggerDto = new QuartzTriggerDetailDto();
            triggerDto.setTriggerName(trigger.getKey().getName());
            triggerDto.setTriggerGroup(trigger.getKey().getGroup());
            triggerDto.setDescription(trigger.getDescription());
            if (trigger instanceof CronTriggerImpl) {
                CronTriggerImpl cronTriggerImpl = (CronTriggerImpl) trigger;
                String cronExpression = cronTriggerImpl.getCronExpression();
                triggerDto.setCron(cronExpression);
                // 最近10次的觸發(fā)時(shí)間
                List<Date> dates = TriggerUtils.computeFireTimes(cronTriggerImpl, null, 10);
                triggerDto.setRecentFireTimeList(dates);
            }
            Trigger.TriggerState triggerState = scheduler.getTriggerState(trigger.getKey());
            triggerDto.setTriggerState(triggerState.toString());
            triggerDtoList.add(triggerDto);
        }
        jobDto.setTriggerDetailDtoList(triggerDtoList);
        return jobDto;
    }
}

接口層

@RestController
public class QuartzController {
    @Autowired
    private QuartzServiceImpl quartzService;
    @PostMapping("/quartz/addJob")
    public void addJob(@RequestBody QuartzCreateParam param) throws SchedulerException {
        quartzService.addJob(param);
    }
    @PostMapping("/quartz/updateJob")
    public void updateJob(@RequestBody QuartzUpdateParam param) throws SchedulerException {
        quartzService.updateJob(param);
    }
    @PostMapping("/quartz/pauseJob")
    public void pauseJob(@RequestBody QuartzDetailParam param) throws SchedulerException {
        quartzService.pauseJob(param);
    }
    @PostMapping("/quartz/resumeJob")
    public void resumeJob(@RequestBody QuartzDetailParam param) throws SchedulerException {
        quartzService.resumeJob(param);
    }
    @PostMapping("/quartz/deleteJob")
    public void deleteJob(@RequestBody QuartzDetailParam param) throws SchedulerException {
        quartzService.deleteJob(param);
    }
    @PostMapping("/quartz/jobList")
    public List<QuartzJobDetailDto> jobList() throws SchedulerException {
        return quartzService.jobList();
    }
    @PostMapping("/quartz/jobDetail")
    public QuartzJobDetailDto jobDetail(@RequestBody QuartzDetailParam param) throws SchedulerException {
        return quartzService.jobDetail(param);
    }
}

接口請(qǐng)求參數(shù)

@ApiModel(value = "Quartz任務(wù)添加請(qǐng)求參數(shù)")
public class QuartzCreateParam extends BaseParam {
    @NotBlank(message = "任務(wù)類不能為空")
    @ApiModelProperty(value = "任務(wù)類路徑", required = true)
    private String jobClazz;
    @NotBlank(message = "任務(wù)類名不能為空")
    @ApiModelProperty(value = "任務(wù)類名", required = true)
    private String jobName;
    /**
     * 組名+任務(wù)類key組成唯一標(biāo)識(shí),所以如果這個(gè)參數(shù)為空,那么默認(rèn)以任務(wù)類key作為組名
     */
    @ApiModelProperty(value = "任務(wù)組名,命名空間")
    private String jobGroup;
    @ApiModelProperty(value = "任務(wù)數(shù)據(jù)")
    private Map<String, Object> jobDataMap;
    @ApiModelProperty(value = "cron表達(dá)式")
    private String cron;
    @ApiModelProperty(value = "描述")
    private String description;
}
@ApiModel(value = "Quartz任務(wù)更新請(qǐng)求參數(shù)")
public class QuartzUpdateParam extends BaseParam {
    @NotBlank(message = "任務(wù)類名不能為空")
    @ApiModelProperty(value = "任務(wù)類名", required = true)
    private String jobName;
    @ApiModelProperty(value = "任務(wù)組名,命名空間")
    private String jobGroup;
    @ApiModelProperty(value = "cron表達(dá)式")
    private String cron;
}
@ApiModel(value = "Quartz任務(wù)詳情請(qǐng)求參數(shù)")
public class QuartzDetailParam extends BaseParam {
    @NotBlank(message = "任務(wù)類名不能為空")
    @ApiModelProperty(value = "任務(wù)類名", required = true)
    private String jobName;
    @ApiModelProperty(value = "任務(wù)組名,命名空間")
    private String jobGroup;
}

接口返回結(jié)果類

@ApiModel(value = "Quartz定時(shí)任務(wù)詳情類")
public class QuartzJobDetailDto {
    @ApiModelProperty(value = "任務(wù)類路徑")
    private String jobClazz;
    @ApiModelProperty(value = "任務(wù)類名")
    private String jobName;
    @ApiModelProperty(value = "任務(wù)組名,命名空間")
    private String jobGroup;
    @ApiModelProperty(value = "任務(wù)數(shù)據(jù)")
    private Map<String, Object> jobDataMap;
    @ApiModelProperty(value = "觸發(fā)器列表")
    private List<QuartzTriggerDetailDto> triggerDetailDtoList;
}
@ApiModel(value = "Quartz定時(shí)任務(wù)觸發(fā)器詳情類")
public class QuartzTriggerDetailDto {
    private String triggerName;
    private String triggerGroup;
    private String cron;
    private String description;
    private String triggerState;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private List<Date> recentFireTimeList;
}

調(diào)用接口進(jìn)行測(cè)試

寫完接口代碼后,我們來測(cè)試一下

添加任務(wù)接口:/quartz/addJob

{
    "jobClazz": "com.cc.job.QuartzTestJob",
    "jobName": "QuartzTestJob",
    "cron": "1/2 * * * * ? ",
    "description": "測(cè)試定時(shí)任務(wù)",
    "jobDataMap": {
        "key": "value"
    }
}

修改任務(wù)接口:/quartz/updateJob

{
    "jobName": "QuartzTestJob",
    "cron": "0/2 * * * * ?"
}

修改任務(wù)只能修改cron時(shí)間,如果想要修改其他內(nèi)容,只能刪除任務(wù)后重新添加。

刪除任務(wù)接口:/quartz/updateJob

{
    "jobName": "QuartzTestJob"
}

暫停、恢復(fù)、詳情接口同刪除任務(wù)接口的請(qǐng)求參數(shù),就不贅述了。

任務(wù)列表:/quartz/jobList

{}

返回結(jié)果:

{
    "code": 10000,
    "msg": "請(qǐng)求成功",
    "data": [
        {
            "jobClazz": "class com.cc.job.QuartzTestJob",
            "jobName": "QuartzTestJob",
            "jobGroup": "DEFAULT",
            "jobDataMap": {
                "key": "value"
            },
            "triggerDetailDtoList": [
                {
                    "triggerName": "DEFAULTQuartzTestJob",
                    "triggerGroup": "DEFAULT",
                    "cron": "0/2 * * * * ?",
                    "description": null,
                    "triggerState": "NORMAL",
                    "recentFireTimeList": [
                        "2023-07-19 09:23:16",
                        "2023-07-19 09:23:18",
                        "2023-07-19 09:23:20",
                        "2023-07-19 09:23:22",
                        "2023-07-19 09:23:24",
                        "2023-07-19 09:23:26",
                        "2023-07-19 09:23:28",
                        "2023-07-19 09:23:30",
                        "2023-07-19 09:23:32",
                        "2023-07-19 09:23:34"
                    ]
                }
            ]
        }
    ],
    "traceId": null,
    "success": true
}

以上就是SpringBoot整合Quartz實(shí)現(xiàn)動(dòng)態(tài)配置的詳細(xì)內(nèi)容,更多關(guān)于Spring Boot整合Quartz實(shí)現(xiàn)動(dòng)態(tài)配置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springboot自定義starter方法及注解實(shí)例

    springboot自定義starter方法及注解實(shí)例

    這篇文章主要為大家介紹了springboot自定義starter方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08
  • MyBatis?Mapper映射器的具體用法

    MyBatis?Mapper映射器的具體用法

    映射器是MyBatis中最重要的文件,映射器由Java接口和XML文件共同組成,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • 詳解java CountDownLatch和CyclicBarrier在內(nèi)部實(shí)現(xiàn)和場(chǎng)景上的區(qū)別

    詳解java CountDownLatch和CyclicBarrier在內(nèi)部實(shí)現(xiàn)和場(chǎng)景上的區(qū)別

    這篇文章主要介紹了詳解java CountDownLatch和CyclicBarrier在內(nèi)部實(shí)現(xiàn)和場(chǎng)景上的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Java編程之如何通過JSP實(shí)現(xiàn)頭像自定義上傳

    Java編程之如何通過JSP實(shí)現(xiàn)頭像自定義上傳

    之前做這個(gè)頭像上傳功能還是花了好多時(shí)間的,今天我將我的代碼分享給大家,下面這篇文章主要給大家介紹了關(guān)于Java編程之如何通過JSP實(shí)現(xiàn)頭像自定義上傳的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • Java中g(shù)et/post的https請(qǐng)求忽略ssl證書認(rèn)證淺析

    Java中g(shù)et/post的https請(qǐng)求忽略ssl證書認(rèn)證淺析

    因?yàn)镴ava在安裝的時(shí)候,會(huì)默認(rèn)導(dǎo)入某些根證書,所以有些網(wǎng)站不導(dǎo)入證書,也可以使用Java進(jìn)行訪問,這篇文章主要給大家介紹了關(guān)于Java中g(shù)et/post的https請(qǐng)求忽略ssl證書認(rèn)證的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • 超詳細(xì)講解Java異常

    超詳細(xì)講解Java異常

    Java 異常機(jī)制可以使程序中異常處理代碼和正常業(yè)務(wù)代碼分離,保證程序代碼更加優(yōu)雅,并提高程序健壯性。本文超詳細(xì)講解了Java異常,感興趣的小伙伴可以參考一下這篇文章
    2021-09-09
  • Java 中的 NoSuchMethodException 異常及解決思路(最新推薦)

    Java 中的 NoSuchMethodException 異常及解決思路(最新推薦)

    NoSuchMethodException異常是Java中使用反射機(jī)制時(shí)常見的錯(cuò)誤,它通常由方法名或參數(shù)不匹配、訪問權(quán)限問題、方法簽名不匹配等原因引發(fā),解決方法包括核實(shí)方法名及其參數(shù)類型、確認(rèn)方法訪問權(quán)限、檢查方法簽名和重載問題、確保方法存在于正確的類中,感興趣的朋友一起看看吧
    2025-01-01
  • mybatis-plus實(shí)現(xiàn)邏輯刪除的示例代碼

    mybatis-plus實(shí)現(xiàn)邏輯刪除的示例代碼

    在大多數(shù)公司里,都會(huì)采用邏輯刪除的方式,本文主要介紹了mybatis-plus實(shí)現(xiàn)邏輯刪除的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-05-05
  • spring集成okhttp3的步驟詳解

    spring集成okhttp3的步驟詳解

    okhttp是一個(gè)封裝URL,比HttpClient更友好易用的工具,下面這篇文章主要給大家介紹了關(guān)于spring集成okhttp3的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起看看吧。
    2018-04-04
  • 基于java配置nginx獲取真實(shí)IP代碼實(shí)例

    基于java配置nginx獲取真實(shí)IP代碼實(shí)例

    這篇文章主要介紹了基于java配置nginx獲取真實(shí)IP代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09

最新評(píng)論