• Quartz 基本使用,任务调度quartz详解,动态定时任务,job,Trigger,Scheduler


    一,Quartz的核心概念

    Quartz是什么?Quartz是一个强大任务调度框架,可以用来干嘛?如一个OA系统需要在每周五9点自动生成数据报表,或者想每月10号自动还款,又或者每周给暗恋的女生定时发送邮件等等。下面介绍Quartz的三个核心概念(job,Trigger,Scheduler

    导入依赖:

    1. <dependency>
    2. <groupId>org.springframework.bootgroupId>
    3. <artifactId>spring-boot-starter-quartzartifactId>
    4. dependency>

    1,任务job

    job就是你想实现的任务类,每一个job必须实现org.quartz.job接口,且只需实现接口定义的execute()方法。

    Job:工作任务调度的接口,任务类需要实现该接口,该接口中定义execute方法,类似jdk提供的TimeTask类的run方法,在里面编写任务执行的业务逻辑。

    例如:

    1. import org.quartz.Job;
    2. import org.quartz.JobDataMap;
    3. import org.quartz.JobExecutionContext;
    4. import org.quartz.JobExecutionException;
    5. import org.slf4j.Logger;
    6. import org.slf4j.LoggerFactory;
    7. /**
    8. * @create: 2022-09-17
    9. **/
    10. public class ScheduleExportJobDTO implements Job {
    11. private final Logger logger = LoggerFactory.getLogger(this.getClass());
    12. @Override
    13. public void execute(JobExecutionContext context) throws JobExecutionException {
    14. try {
    15. JobDataMap jobDataMap = context.getMergedJobDataMap();
    16. Integer documentId = jobDataMap.getInt("documentId");
    17. logger.info("执行导出任务,documentId:{}", documentId);
    18. //这个下面调用的就是你想执行的任务方法,我这里是调用一个类里面的导出任务。
    19. ICEDEvidenceDocumentExportScheduleManager exportScheduleManager = SpringUtils.getBean(ICEDEvidenceDocumentExportScheduleManager.class);
    20. exportScheduleManager.scheduleExport(documentId);
    21. }catch (Exception e){
    22. logger.info("执行导出任务失败, msg:{}", e.getMessage());
    23. context.setResult(null);
    24. throw new JobExecutionException("执行导出任务失败",e);
    25. }
    26. }
    27. }


    JobDetall :使用JobDetail来定义定时任务的实例,JobDetail实例是通过JobBuilder类创建。实例在Quartz中的生命周期,每次调度器执行job时它在调用execute方法前,会创建一个新的job实例,当调用完成后,关联
    的job对象实例会被是释放,释放的实例会被垃圾回收机制回收。

    例如:

    1. JobDetail jobDetail=JobBuilder.newJob(ScheduleExportJobDTO .class)//加载任务类,与任务类绑定
    2. .withIdentity("job", "group")//参数1:任务名称,参数2:组名称
    3. .usingJobData("dataMap", "message")//可以设置JobDataMap,获取存取信息
    4. .build();//创建实例

    2,触发器Trigger
    Trigger 为你执行任务的触发器,比如你想每天定时1点发送邮件,Trigger将会设置1点执行该任务。
    Trigger主要包含两种:SimpleTrigger和CronTriggerr。

    Trgger触发器 Trigger对象是用于触发执行Job的,当调度一个Job时,我们实例一个触发器然后调整它的属性来满足Job执行的条件,表明任务在什么时候执行。定义了一个已经被安排的任务将在什么时候执行的时间条件,比如每秒执行一次。

    例如:

    1. //2,触发器,Quartz里有多个触发器,最常用的是SimpleTrigger,CronTrigger;
    2. SimpleTrigger trigger=TriggerBuilder.newTrigger().withIdentity("trigger", "group")
    3. .withSchedule(SimpleScheduleBuilder.simpleSchedule()//属性有开始时间,结束时间,重复次数,重复时间间隔
    4. .repeatSecondlyForTotalCount(5, 1))//参数1:count,参数2:second.每一秒重复执行,总共执行3遍
    5. // .startNow()//立刻执行
    6. .startAt(new Date())//设置任务开始时间
    7. .endAt(date)//设置任务结束时间
    8. .build();
    1. //触发器
    2. CronTrigger trigger=TriggerBuilder.newTrigger().withIdentity("trigger", "group").startNow()//立刻执行
    3. .withSchedule(CronScheduleBuilder.cronSchedule("0 * * * * ?"))//表示每次0秒时候执行。
    4. .build();


    3,调度器Scheduler
    Scheduler是任务的调度器,会将任务job和触发器TRigger结合,负责基于Trigger设定的时间执行job。

     

    1. // 方法之二:从工厂中获取默认的
    2. Scheduler scheduler=StdSchedulerFactory.getDefaultScheduler();
    3. scheduler.scheduleJob(jobDetail,trigger);//关联两者
    1. //方法之一
    2. @Autowired
    3. private Scheduler scheduler;
    4. scheduler.scheduleJob(jobDetail, trigger);

    4.JobDataMap 可包含数据对象,在job实例执行的是好,可使用包含的数据;JobDataMap是java Map接口的实现,增加了一些存取基本类型方法。

    案例提供:

            需求关于对导出文档这个任务实现定时策略。

            关键代码:包含二个类   1.job类,实现导出任务的任务类,只在execute方法中实现了导出任务。

                                                   2.ScheduleManager管理类,其中有addJob-增加定时导出文档任务,startJob-恢复定时导出文档任务(若以往没有该任务则新增定时导出任务),stopJob-停止定时导出文档任务,getScheduler-获取当前正在执行的定时导出文档任务。

    1.job类

    1. import org.quartz.Job;
    2. import org.quartz.JobDataMap;
    3. import org.quartz.JobExecutionContext;
    4. import org.quartz.JobExecutionException;
    5. import org.slf4j.Logger;
    6. import org.slf4j.LoggerFactory;
    7. /**
    8. * @create: 2022-09-17
    9. **/
    10. public class ScheduleExportJobDTO implements Job {
    11. private final Logger logger = LoggerFactory.getLogger(this.getClass());
    12. @Override
    13. public void execute(JobExecutionContext context) throws JobExecutionException {
    14. try {
    15. JobDataMap jobDataMap = context.getMergedJobDataMap();
    16. Integer documentId = jobDataMap.getInt("documentId");
    17. logger.info("执行导出任务,documentId:{}", documentId);
    18. //这个下面调用的就是你想执行的任务方法,我这里是调用一个类里面的导出任务。
    19. ICEDEvidenceDocumentExportScheduleManager exportScheduleManager = SpringUtils.getBean(ICEDEvidenceDocumentExportScheduleManager.class);
    20. exportScheduleManager.scheduleExport(documentId);
    21. }catch (Exception e){
    22. logger.info("执行导出任务失败, msg:{}", e.getMessage());
    23. context.setResult(null);
    24. throw new JobExecutionException("执行导出任务失败",e);
    25. }
    26. }
    27. }

    2.ScheduleManager管理类

    1. import org.quartz.*;
    2. import org.slf4j.Logger;
    3. import org.slf4j.LoggerFactory;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.stereotype.Component;
    6. import java.util.ArrayList;
    7. import java.util.Date;
    8. import java.util.List;
    9. /**
    10. * @create: 2022-09-18
    11. **/
    12. @Component
    13. public class ICEDEvidenceDocumentExportScheduleManager {
    14. @Autowired
    15. private ICEDEvidenceDocumentExportScheduleMapper exportScheduleMapper;
    16. @Autowired
    17. private ICEDEvidenceDocumentManager documentManager;
    18. @Autowired
    19. private ICEDEvidenceDocumentExportManager documentExportManager;
    20. @Autowired
    21. private ICEDEvidenceDocumentStructureMapper documentStructureMapper;
    22. @Autowired
    23. private ICEDEvidenceDocumentOperationLogService operationLogService;
    24. @Autowired
    25. private ICEDEvidenceDocumentService documentService;
    26. @Autowired
    27. private TokenService tokenService;
    28. @Autowired
    29. private Scheduler scheduler;
    30. private final CopyOptions copyOptions = CopyOptions.create(null, true);
    31. private static final String JOB_NAME_PREFIX = "export-job-";
    32. private static final String TRIGGER_NAME_PREFIX = "export-trigger-";
    33. private static final Integer ADMIN_USER_ID = 1;
    34. private final Logger logger = LoggerFactory.getLogger(this.getClass());
    35. public void addJob(Integer documentId, String cronExpression) throws SchedulerException {
    36. JobKey jobKey = getJobKey(documentId);
    37. logger.info("创建调度任务 jobKey:{}, cronExpression:{}", jobKey, cronExpression);
    38. JobDetail jobDetail = JobBuilder.newJob(ScheduleExportJobDTO.class)
    39. .withIdentity(jobKey)
    40. .usingJobData("documentId", documentId)
    41. .build();
    42. CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(documentId))
    43. .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
    44. .build();
    45. scheduler.scheduleJob(jobDetail, trigger);
    46. }
    47. public void startJob(Integer documentId, String cronExpression) throws SchedulerException {
    48. JobKey jobKey = getJobKey(documentId);
    49. if (scheduler.checkExists(jobKey)){
    50. logger.info("恢复调度任务 jobKey:{}", jobKey);
    51. scheduler.resumeJob(jobKey);
    52. }else {
    53. logger.info("创建调度任务 jobKey:{}, cronExpression:{}", jobKey, cronExpression);
    54. JobDetail jobDetail = JobBuilder.newJob(ScheduleExportJobDTO.class)
    55. .withIdentity(getJobKey(documentId))
    56. .usingJobData("documentId", documentId)
    57. .build();
    58. CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(documentId))
    59. .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
    60. .build();
    61. scheduler.scheduleJob(jobDetail, trigger);
    62. }
    63. }
    64. public void stopJob(Integer documentId) throws SchedulerException {
    65. JobKey jobKey = getJobKey(documentId);
    66. logger.info("停止调度任务 jobKey:{}", jobKey);
    67. scheduler.pauseJob(jobKey);
    68. }
    69. private JobKey getJobKey(Integer documentId){
    70. return JobKey.jobKey(JOB_NAME_PREFIX + documentId);
    71. }
    72. private TriggerKey getTriggerKey(Integer documentId){
    73. return TriggerKey.triggerKey(TRIGGER_NAME_PREFIX + documentId);
    74. }
    75. public Integer saveExportSchedule(ICEDEvidenceDocumentExportScheduleReqDTO exportScheduleReqDTO) {
    76. Integer loginUserId = getLoginUserId();
    77. Integer loginUserDeptId = getLoginUserDeptId();
    78. Date now = new Date();
    79. ICEDEvidenceDocumentExportSchedule exportSchedule = new ICEDEvidenceDocumentExportSchedule();
    80. BeanUtil.copyProperties(exportScheduleReqDTO, exportSchedule, copyOptions);
    81. exportSchedule.setOper(loginUserId);
    82. exportSchedule.setUpdator(loginUserId);
    83. exportSchedule.setOpTime(now);
    84. exportSchedule.setUpdateTime(now);
    85. exportSchedule.setDeptId(loginUserDeptId);
    86. exportScheduleMapper.insertSelective(exportSchedule);
    87. return exportSchedule.getId();
    88. }
    89. public void scheduleExport(Integer documentId){
    90. ICEvidenceDocument document = documentManager.getEvidenceDocument(documentId);
    91. List documentStructureList = documentStructureMapper.selectChapterDocumentStructure(documentId);
    92. List dataDTOList = new ArrayList<>();
    93. for (ICEDEvidenceDocumentStructure documentStructure : documentStructureList) {
    94. //dataTree 中已经进行权限过滤
    95. dataDTOList.add(documentService.dataTree(documentStructure.getId()));
    96. }
    97. logger.info("查询导出文档数据完成");
    98. //记录操作日志
    99. Integer operationLogId = operationLogService.recordLogBeforeOperation(documentId,
    100. ICEDEvidenceDocumentOperationType.EXPORT, dataDTOList, null);
    101. logger.info("记录导出文档操作日志,operationLogId:{}, status: {}", operationLogId, ICEDEvidenceDocumentOperationStatus.getStatusMeaning(ICEDEvidenceDocumentOperationStatus.OPERATING));
    102. documentExportManager.scheduleExport(document.getTemplateId(), dataDTOList, operationLogId, ADMIN_USER_ID);
    103. }
    104. public Integer getLoginUserId(){
    105. LoginUser loginUser = tokenService.getLoginUser();
    106. if (loginUser == null){
    107. throw new CheckedException("获取当前登录用户失败");
    108. }
    109. return Math.toIntExact(loginUser.getUserid());
    110. }
    111. public Integer getLoginUserDeptId(){
    112. LoginUser loginUser = tokenService.getLoginUser();
    113. if (loginUser == null){
    114. throw new CheckedException("获取当前登录用户失败");
    115. }
    116. SysUser sysUser = loginUser.getSysUser();
    117. if (sysUser == null){
    118. throw new CheckedException("获取当前登录用户信息失败");
    119. }
    120. return Math.toIntExact(sysUser.getDeptId());
    121. }
    122. public String getScheduler() throws SchedulerException {
    123. List currentlyExecutingJobList = scheduler.getCurrentlyExecutingJobs();
    124. return JSON.toJSONString(currentlyExecutingJobList);
    125. }
    126. }
  • 相关阅读:
    我的世界Minecraft基岩版开服服务器教程(Windows)开服器开服包下载开服网站服务器要多少钱开服核心开服端下载
    玩机搞机---mtk芯片机型线刷救砖的一些基本解决方法和步骤解析 mtk报错代码 SP_Flash平台刷机
    abortControllerMap: Map<string, AbortController>
    JavaScript基础——巩固练习(3)
    Vue模板语法的缩写是什么?
    Jupyter Notebook 怎么在虚拟环境之间切换
    如何破解压缩包密码,CTF压缩包处理
    商业网络中数字孪生的未开发潜力
    关于Comparable、Comparator接口返回值决定顺序的问题
    0704~springboot整合ES&RabbitMQ
  • 原文地址:https://blog.csdn.net/qq_48964306/article/details/126935096