From 0574f0774d49b9b84c5780f12c25a090f0b9f32d Mon Sep 17 00:00:00 2001 From: liuminglei <812934656@qq.com> Date: Fri, 11 Jan 2019 17:30:17 +0800 Subject: [PATCH 1/3] =?UTF-8?q?2.0.0=E5=88=9D=E5=A7=8B=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/xbd/quartz/DefaultQuartzJobBean.java | 112 +-- src/main/java/com/xbd/quartz/QuartzJob.java | 100 ++ .../java/com/xbd/quartz/QuartzJobBuilder.java | 133 +++ .../com/xbd/quartz/QuartzTaskHandler.java | 864 ++++++++++++++++-- .../java/com/xbd/quartz/QuartzTrigger.java | 246 +++++ .../com/xbd/quartz/QuartzTriggerBuilder.java | 231 +++++ .../handler/DefaultQuartzTaskHandler.java | 501 ++++++---- 7 files changed, 1860 insertions(+), 327 deletions(-) create mode 100644 src/main/java/com/xbd/quartz/QuartzJob.java create mode 100644 src/main/java/com/xbd/quartz/QuartzJobBuilder.java create mode 100644 src/main/java/com/xbd/quartz/QuartzTrigger.java create mode 100644 src/main/java/com/xbd/quartz/QuartzTriggerBuilder.java diff --git a/src/main/java/com/xbd/quartz/DefaultQuartzJobBean.java b/src/main/java/com/xbd/quartz/DefaultQuartzJobBean.java index bb5338b..2d67674 100644 --- a/src/main/java/com/xbd/quartz/DefaultQuartzJobBean.java +++ b/src/main/java/com/xbd/quartz/DefaultQuartzJobBean.java @@ -1,125 +1,37 @@ package com.xbd.quartz; -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.JSONArray; -import com.alibaba.fastjson.JSONObject; -import org.apache.commons.lang3.StringUtils; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.context.ApplicationContext; import org.springframework.scheduling.quartz.QuartzJobBean; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.List; +import java.time.LocalDateTime; /** - *
* 默认定时任务QuartzJobBean - *
+ * 将声明的{@code QuartzJob}添加到{@code Scheduler}中 + *
+ * 将声明的{@code QuartzJob}更新到{@code Scheduler}中,任务可以是正在运行的状态,也没问题 + *
将已暂停的任务恢复运行状态
立即触发一次任务
+ * 将声明的{@code QuartzJob}从{@code Scheduler}中删除 + *
+ * 将{@code Scheduler}中的所有任务暂停 + *
{@link Trigger}
Calendar
replace
false
+ * If removal of the Calendar would result in + * Triggers pointing to non-existent calendars, then a + * SchedulerException will be thrown. + *
Trigger
SchedulerException
{@link Calendar}
{@link Calendar}s
Scheduler
+ * 通用策略 + *
+ * SimpleTrigger对应的策略 + *
+ * CronTrigger对应的策略 + *
QuartzTaskHandler
+ * SpringBoot项目 + * {@code @Bean} + * public DefaultQuartzTaskHandler defaultQuartzTaskHandler() { + * DefaultQuartzTaskHandler defaultQuartzTaskHandler = new DefaultQuartzTaskHandler(); + * defaultQuartzTaskHandler.setScheduler(scheduler); + * return defaultQuartzTaskHandler; + * } + * + * 同样也可以用在SpringMVC项目中: + * {@code } + * {@code } + * {@code } + *
* 自动装载Bean到Spring,可在JobBean中直接注入定义的Bean - *
包含JobKey、description、jobClass、jobData、durability、shouldRecover、triggers. * * @author luas * @since 2.0 @@ -22,7 +22,7 @@ public class QuartzJob implements Serializable { private String description; - private Class extends DefaultQuartzJobBean> jobClass; + private Class extends AbstractQuartzJobBean> jobClass; private Map jobData; @@ -58,11 +58,11 @@ public class QuartzJob implements Serializable { this.description = description; } - public Class extends DefaultQuartzJobBean> getJobClass() { + public Class extends AbstractQuartzJobBean> getJobClass() { return jobClass; } - public void setJobClass(Class extends DefaultQuartzJobBean> jobClass) { + public void setJobClass(Class extends AbstractQuartzJobBean> jobClass) { this.jobClass = jobClass; } diff --git a/src/main/java/com/xbd/quartz/QuartzJobBuilder.java b/src/main/java/com/xbd/quartz/QuartzJobBuilder.java index f19309e..3ab1814 100644 --- a/src/main/java/com/xbd/quartz/QuartzJobBuilder.java +++ b/src/main/java/com/xbd/quartz/QuartzJobBuilder.java @@ -8,13 +8,18 @@ import java.util.Set; import org.quartz.JobKey; import org.quartz.utils.Key; +/** + * {@code QuartzJob} to {@link org.quartz.JobDetail} + * @author luas + * @since 2.0 + */ public class QuartzJobBuilder { private JobKey key; private String description; - private Class extends DefaultQuartzJobBean> jobClass; + private Class extends AbstractQuartzJobBean> jobClass; private Map jobData = new HashMap<>(); @@ -28,9 +33,9 @@ public class QuartzJobBuilder { return new QuartzJobBuilder(); } - public static QuartzJobBuilder newJob(Class extends DefaultQuartzJobBean> jobClass) { + public static QuartzJobBuilder newJob(Class extends AbstractQuartzJobBean> jobClass) { QuartzJobBuilder builder = new QuartzJobBuilder(); - builder.ofType(jobClass); + builder.forJob(jobClass); return builder; } @@ -78,7 +83,7 @@ public class QuartzJobBuilder { return this; } - public QuartzJobBuilder ofType(Class extends DefaultQuartzJobBean> jobClazz) { + public QuartzJobBuilder forJob(Class extends AbstractQuartzJobBean> jobClazz) { this.jobClass = jobClazz; return this; } diff --git a/src/main/java/com/xbd/quartz/QuartzListenerRegister.java b/src/main/java/com/xbd/quartz/QuartzListenerRegister.java index d6cf92c..be4ffc9 100644 --- a/src/main/java/com/xbd/quartz/QuartzListenerRegister.java +++ b/src/main/java/com/xbd/quartz/QuartzListenerRegister.java @@ -15,11 +15,10 @@ import org.springframework.context.ApplicationContextAware; import java.util.Map; /** - * * JobListener、SchedulerListener、TriggerListener自动注册监听 - * * * @author 小不点 + * @since 1.0 */ public class QuartzListenerRegister implements ApplicationContextAware, InitializingBean { diff --git a/src/main/java/com/xbd/quartz/QuartzTask.java b/src/main/java/com/xbd/quartz/QuartzTask.java index f4ccdf7..f99fec8 100644 --- a/src/main/java/com/xbd/quartz/QuartzTask.java +++ b/src/main/java/com/xbd/quartz/QuartzTask.java @@ -3,6 +3,13 @@ package com.xbd.quartz; import java.io.Serializable; import java.util.Date; +/** + * 定时任务实体 + * 此类已不再使用,请使用{@link QuartzJob}、{@link QuartzTrigger}组织定时任务. + * @author luas + * @since 1.0 + */ +@Deprecated public class QuartzTask implements Serializable { private String name; diff --git a/src/main/java/com/xbd/quartz/QuartzTaskHandler.java b/src/main/java/com/xbd/quartz/QuartzTaskHandler.java index 56d6f0c..73631fe 100644 --- a/src/main/java/com/xbd/quartz/QuartzTaskHandler.java +++ b/src/main/java/com/xbd/quartz/QuartzTaskHandler.java @@ -26,6 +26,152 @@ public abstract class QuartzTaskHandler { @NonNull protected Scheduler scheduler; + /** + * 动态添加任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void addTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量动态添加任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void addTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 动态更新任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void updateTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量动态更新任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void updateTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 暂停任务 + * + * @see QuartzTask + * + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void pauseTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量暂停任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void pauseTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 暂停所有任务 + * + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void pauseTask() throws SchedulerException; + + /** + * 继续任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void resumeTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量继续任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void resumeTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 删除任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void deleteTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量删除任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void deleteTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 根据定时任务信息组织CronScheduleBuilder + * + * @see CronScheduleBuilder + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @since 1.0 + */ + @Deprecated + public CronScheduleBuilder initCronScheduleBuilder(QuartzTask quartzTask) { + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartzTask.getCronExpression()); + + // 以当前时间为触发频率立刻触发一次执行,然后按照Cron频率依次执行 + if (quartzTask.getMisfireInstruction() == CronTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW) { + cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed(); + } else if (quartzTask.getMisfireInstruction() == CronTrigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY) { + // 以错过的第一个频率时间立刻开始执行,重做错过的所有频率周期后,当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行 + cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); + } else if (quartzTask.getMisfireInstruction() == CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING) { + // 不触发立即执行,等待下次Cron触发频率到达时刻开始按照Cron频率依次执行 + cronScheduleBuilder.withMisfireHandlingInstructionDoNothing(); + } + + return cronScheduleBuilder; + } + /** * 动态添加任务 * diff --git a/src/main/java/com/xbd/quartz/QuartzTriggerBuilder.java b/src/main/java/com/xbd/quartz/QuartzTriggerBuilder.java index a1b98b8..e37b7ec 100644 --- a/src/main/java/com/xbd/quartz/QuartzTriggerBuilder.java +++ b/src/main/java/com/xbd/quartz/QuartzTriggerBuilder.java @@ -7,6 +7,11 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; +/** + * {@code QuartzTrigger} to {@link Trigger} + * @author luas + * @since 2.0 + */ public class QuartzTriggerBuilder { private QuartzTrigger.TriggerType type = QuartzTrigger.TriggerType.SIMPLE; diff --git a/src/main/java/com/xbd/quartz/configure/QuartzProperties.java b/src/main/java/com/xbd/quartz/configure/QuartzProperties.java index cb376ad..3b113c9 100644 --- a/src/main/java/com/xbd/quartz/configure/QuartzProperties.java +++ b/src/main/java/com/xbd/quartz/configure/QuartzProperties.java @@ -3,6 +3,10 @@ package com.xbd.quartz.configure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.io.Resource; +/** + * @author luas + * @since 1.0 + */ @ConfigurationProperties(prefix = "sys.quartz") public class QuartzProperties { diff --git a/src/main/java/com/xbd/quartz/handler/DefaultQuartzTaskHandler.java b/src/main/java/com/xbd/quartz/handler/DefaultQuartzTaskHandler.java index db96f6e..3669e3d 100644 --- a/src/main/java/com/xbd/quartz/handler/DefaultQuartzTaskHandler.java +++ b/src/main/java/com/xbd/quartz/handler/DefaultQuartzTaskHandler.java @@ -5,39 +5,263 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.xbd.quartz.QuartzJob; -import com.xbd.quartz.QuartzTaskHandler; -import com.xbd.quartz.QuartzTrigger; +import com.xbd.quartz.*; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.quartz.*; import org.quartz.impl.matchers.GroupMatcher; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** - * QuartzTaskHandler的默认实现 - * + * {@code QuartzTaskHandler}的默认实现 + * 配置方式如下: * - * SpringBoot项目 - * {@code @Bean} + * java配置: + * {@code + * @Bean * public DefaultQuartzTaskHandler defaultQuartzTaskHandler() { * DefaultQuartzTaskHandler defaultQuartzTaskHandler = new DefaultQuartzTaskHandler(); * defaultQuartzTaskHandler.setScheduler(scheduler); * return defaultQuartzTaskHandler; * } + * } * - * 同样也可以用在SpringMVC项目中: - * {@code } - * {@code } - * {@code } + * xml配置: + * {@code + * + * + * + * } * * - * @author 刘明磊 + * @author luas * @since 1.0 */ public class DefaultQuartzTaskHandler extends QuartzTaskHandler { + /** + * 动态添加任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void addTask(QuartzTask quartzTask) throws SchedulerException { + JobDetail jobDetail = JobBuilder + .newJob(DefaultQuartzJobBean.class) + .withIdentity(quartzTask.getName(), quartzTask.getGroup()) + .withDescription(quartzTask.getDescription()) + .storeDurably() + .build(); + + CronScheduleBuilder cronScheduleBuilder = initCronScheduleBuilder(quartzTask); + + TriggerBuilder triggerBuilder = TriggerBuilder.newTrigger() + .withIdentity(TriggerKey.triggerKey(quartzTask.getName(), quartzTask.getGroup())) + .withSchedule(cronScheduleBuilder) + .usingJobData(DefaultQuartzJobBean.JOBDETAIL_KEY_TARGETCLASS, quartzTask.getTargetClass()) + .usingJobData(DefaultQuartzJobBean.JOBDETAIL_KEY_TARGETOBJECT, quartzTask.getTargetObject()) + .usingJobData(DefaultQuartzJobBean.JOBDETAIL_KEY_TARGETMETHOD, StringUtils.isBlank(quartzTask.getTargetMethod()) ? DefaultQuartzJobBean.JOBDETAIL_VALUE_TARGETMETHOD : quartzTask.getTargetMethod()) + .usingJobData(DefaultQuartzJobBean.JOBDETAIL_KEY_TARGETMETHOD_PARAM, quartzTask.getTargetMethodParam()); + + if (quartzTask.getStartAt() != null) { + triggerBuilder.startAt(quartzTask.getStartAt()); + } + + if (quartzTask.isStartNow()) { + triggerBuilder.startNow(); + } + + if (quartzTask.getEndAt() != null) { + triggerBuilder.endAt(quartzTask.getEndAt()); + } + + CronTrigger cronTrigger = triggerBuilder.build(); + + scheduler.scheduleJob(jobDetail, cronTrigger); + } + + /** + * 批量动态添加任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void addTask(QuartzTask... quartzTasks) throws SchedulerException { + if (quartzTasks != null) { + for (QuartzTask quartzTask : quartzTasks) { + addTask(quartzTask); + } + } + } + + /** + * 动态更新任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void updateTask(QuartzTask quartzTask) throws SchedulerException { + CronTrigger cronTrigger = (CronTrigger) getTrigger(quartzTask.getName(), quartzTask.getGroup()); + + CronScheduleBuilder cronScheduleBuilder = initCronScheduleBuilder(quartzTask); + + TriggerBuilder triggerBuilder = cronTrigger + .getTriggerBuilder() + .withIdentity(TriggerKey.triggerKey(quartzTask.getName(), quartzTask.getGroup())) + .withSchedule(cronScheduleBuilder) + .usingJobData(DefaultQuartzJobBean.JOBDETAIL_KEY_TARGETCLASS, quartzTask.getTargetClass()) + .usingJobData(DefaultQuartzJobBean.JOBDETAIL_KEY_TARGETOBJECT, quartzTask.getTargetObject()) + .usingJobData(DefaultQuartzJobBean.JOBDETAIL_KEY_TARGETMETHOD, StringUtils.isBlank(quartzTask.getTargetMethod()) ? DefaultQuartzJobBean.JOBDETAIL_VALUE_TARGETMETHOD : quartzTask.getTargetMethod()) + .usingJobData(DefaultQuartzJobBean.JOBDETAIL_KEY_TARGETMETHOD_PARAM, quartzTask.getTargetMethodParam()); + + if (quartzTask.getStartAt() != null) { + triggerBuilder.startAt(quartzTask.getStartAt()); + } + + if (quartzTask.isStartNow()) { + triggerBuilder.startNow(); + } + + if (quartzTask.getEndAt() != null) { + triggerBuilder.endAt(quartzTask.getEndAt()); + } + + cronTrigger = triggerBuilder.build(); + + scheduler.rescheduleJob(TriggerKey.triggerKey(quartzTask.getName(), quartzTask.getGroup()), cronTrigger); + } + + /** + * 批量动态更新任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void updateTask(QuartzTask... quartzTasks) throws SchedulerException { + if (quartzTasks != null) { + for (QuartzTask quartzTask : quartzTasks) { + updateTask(quartzTask); + } + } + } + + /** + * 暂停任务 + * + * @see QuartzTask + * + * @param quartzTask 定时任务信息 + * @throws SchedulerException + */ + public void pauseTask(QuartzTask quartzTask) throws SchedulerException { + JobKey jobKey = new JobKey(quartzTask.getName(), quartzTask.getGroup()); + scheduler.pauseJob(jobKey); + } + + /** + * 批量暂停任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void pauseTask(QuartzTask... quartzTasks) throws SchedulerException { + if (quartzTasks != null) { + for (QuartzTask quartzTask : quartzTasks) { + pauseTask(quartzTask); + } + } + } + + /** + * 暂停所有任务 + * + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void pauseTask() throws SchedulerException { + scheduler.pauseAll(); + } + + /** + * 继续任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void resumeTask(QuartzTask quartzTask) throws SchedulerException { + JobKey jobKey = new JobKey(quartzTask.getName(), quartzTask.getGroup()); + scheduler.resumeJob(jobKey); + } + + /** + * 批量继续任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void resumeTask(QuartzTask... quartzTasks) throws SchedulerException { + if (quartzTasks != null) { + for (QuartzTask quartzTask : quartzTasks) { + resumeTask(quartzTask); + } + } + } + + /** + * 删除任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void deleteTask(QuartzTask quartzTask) throws SchedulerException { + JobKey jobKey = new JobKey(quartzTask.getName(), quartzTask.getGroup()); + scheduler.deleteJob(jobKey); + } + + /** + * 批量删除任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public void deleteTask(QuartzTask... quartzTasks) throws SchedulerException { + if (quartzTasks != null) { + for (QuartzTask quartzTask : quartzTasks) { + deleteTask(quartzTask); + } + } + } + /** * 动态添加任务 */ diff --git a/src/main/java/com/xbd/quartz/listener/AbstractJobListener.java b/src/main/java/com/xbd/quartz/listener/AbstractJobListener.java index 2a2f84f..a669916 100644 --- a/src/main/java/com/xbd/quartz/listener/AbstractJobListener.java +++ b/src/main/java/com/xbd/quartz/listener/AbstractJobListener.java @@ -4,20 +4,21 @@ import org.quartz.JobListener; import org.quartz.Matcher; import org.quartz.TriggerKey; import org.quartz.impl.matchers.EverythingMatcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * - * 自定义JobListener,可匹配任务。定义并配置之后,系统可自动注册 - * + * 自定义JobListener,可匹配任务。定义并配置之后,系统可自动注册 * * @author 小不点 + * @since 1.0 */ public abstract class AbstractJobListener implements JobListener { + protected final Logger logger = LoggerFactory.getLogger(getClass()); + /** - * * 返回匹配某一、某些Job的匹配策略 - * */ public Matcher matcher() { return EverythingMatcher.allTriggers(); diff --git a/src/main/java/com/xbd/quartz/listener/AbstractSchedulerListener.java b/src/main/java/com/xbd/quartz/listener/AbstractSchedulerListener.java index aebcaa9..cc84912 100644 --- a/src/main/java/com/xbd/quartz/listener/AbstractSchedulerListener.java +++ b/src/main/java/com/xbd/quartz/listener/AbstractSchedulerListener.java @@ -1,15 +1,17 @@ package com.xbd.quartz.listener; import org.quartz.SchedulerListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * * 自定义SchedulerListener。定义并配置之后,系统可自动注册 - * * * @author 小不点 + * @since 1.0 */ public abstract class AbstractSchedulerListener implements SchedulerListener { + protected final Logger logger = LoggerFactory.getLogger(getClass()); } diff --git a/src/main/java/com/xbd/quartz/listener/AbstractTriggerListener.java b/src/main/java/com/xbd/quartz/listener/AbstractTriggerListener.java index a7508f3..f99ca04 100644 --- a/src/main/java/com/xbd/quartz/listener/AbstractTriggerListener.java +++ b/src/main/java/com/xbd/quartz/listener/AbstractTriggerListener.java @@ -4,20 +4,21 @@ import org.quartz.Matcher; import org.quartz.TriggerKey; import org.quartz.TriggerListener; import org.quartz.impl.matchers.EverythingMatcher; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** - * * 自定义TriggerListener,可匹配任务。定义并配置之后,系统可自动注册 - * * * @author 小不点 + * @since 1.0 */ public abstract class AbstractTriggerListener implements TriggerListener { + protected final Logger logger = LoggerFactory.getLogger(getClass()); + /** - * * 返回匹配某一、某些Trigger的匹配策略 - * */ public Matcher matcher() { return EverythingMatcher.allTriggers(); diff --git a/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalJobListener.java b/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalJobListener.java new file mode 100644 index 0000000..3b78e6b --- /dev/null +++ b/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalJobListener.java @@ -0,0 +1,60 @@ +package com.xbd.quartz.listener.trigger; + +import com.xbd.quartz.listener.AbstractJobListener; + +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.Matcher; +import org.quartz.TriggerKey; + +import java.time.LocalDateTime; + +/** + * 默认全局JobListener + * + * @author luas + * @since 4.3 + */ +public class DefaultGlobalJobListener extends AbstractJobListener { + + @Override + public String getName() { + return "defaultGlobalJobListener"; + } + + @Override + public Matcher matcher() { + return super.matcher(); + } + + @Override + public void jobToBeExecuted(JobExecutionContext context) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Job {} 即将执行", new Object[] { context.getJobDetail() }); + } + } + + @Override + public void jobExecutionVetoed(JobExecutionContext context) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Job {} 于 {} 被否决,不再执行", + new Object[] { context.getJobDetail(), LocalDateTime.now() }); + } + } + + @Override + public void jobWasExecuted(JobExecutionContext context, + JobExecutionException jobException) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Job {} 于 {} 执行,", + new Object[] { context.getJobDetail(), LocalDateTime.now() }); + + if (jobException != null) { + this.logger.debug("Job {} 执行中发生异常,异常信息为 {},", + new Object[] { context.getJobDetail(), jobException }); + } + } + + } + +} diff --git a/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalSchedulerListener.java b/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalSchedulerListener.java new file mode 100644 index 0000000..c156ad1 --- /dev/null +++ b/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalSchedulerListener.java @@ -0,0 +1,170 @@ +package com.xbd.quartz.listener.trigger; + +import com.xbd.quartz.listener.AbstractSchedulerListener; + +import org.quartz.*; + +import java.time.LocalDateTime; + +/** + * 默认全局SchedulerListener + * + * @author luas + * @since 4.3 + */ +public class DefaultGlobalSchedulerListener extends AbstractSchedulerListener { + + @Override + public void jobScheduled(Trigger trigger) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Job {} 所属 Trigger {} 于 {} 执行调度。", new Object[] { + trigger.getJobKey(), trigger.getKey(), LocalDateTime.now() }); + } + } + + @Override + public void jobUnscheduled(TriggerKey triggerKey) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Trigger {} 未执行调度。", new Object[] { triggerKey }); + } + } + + @Override + public void triggerFinalized(Trigger trigger) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Job {} 所属 Trigger {} 于 {} 调度期结束,不再调度。", new Object[] { + trigger.getJobKey(), trigger.getKey(), LocalDateTime.now() }); + } + } + + @Override + public void triggerPaused(TriggerKey triggerKey) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Trigger {} 于 {} 暂停调度。", + new Object[] { triggerKey, LocalDateTime.now() }); + } + } + + @Override + public void triggersPaused(String triggerGroup) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("TriggerGroup {} 于 {} 暂停调度。", + new Object[] { triggerGroup, LocalDateTime.now() }); + } + } + + @Override + public void triggerResumed(TriggerKey triggerKey) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Trigger {} 于 {} 恢复调度。", + new Object[] { triggerKey, LocalDateTime.now() }); + } + } + + @Override + public void triggersResumed(String triggerGroup) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("TriggerGroup {} 于 {} 恢复调度。", + new Object[] { triggerGroup, LocalDateTime.now() }); + } + } + + @Override + public void jobAdded(JobDetail jobDetail) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Job {} 于 {} 添加到调度器中。", + new Object[] { jobDetail, LocalDateTime.now() }); + } + } + + @Override + public void jobDeleted(JobKey jobKey) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Job {} 于 {} 删除。", + new Object[] { jobKey, LocalDateTime.now() }); + } + } + + @Override + public void jobPaused(JobKey jobKey) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Job {} 于 {} 暂停调度。", + new Object[] { jobKey, LocalDateTime.now() }); + } + } + + @Override + public void jobsPaused(String jobGroup) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("JobGroup {} 于 {} 暂停调度。", + new Object[] { jobGroup, LocalDateTime.now() }); + } + } + + @Override + public void jobResumed(JobKey jobKey) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("Job {} 于 {} 恢复调度。", + new Object[] { jobKey, LocalDateTime.now() }); + } + } + + @Override + public void jobsResumed(String jobGroup) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("JobGroup {} 于 {} 恢复调度。", + new Object[] { jobGroup, LocalDateTime.now() }); + } + } + + @Override + public void schedulerError(String msg, SchedulerException cause) { + if (this.logger.isDebugEnabled()) { + this.logger.debug("调度器 于 {} 发生错误,错误信息 {},异常 {}。", + new Object[] { LocalDateTime.now(), msg, cause }); + } + } + + @Override + public void schedulerInStandbyMode() { + if (this.logger.isDebugEnabled()) { + this.logger.debug("调度器 于 {} 处于待命状态。", new Object[] { LocalDateTime.now() }); + } + } + + @Override + public void schedulerStarted() { + if (this.logger.isDebugEnabled()) { + this.logger.debug("调度器 于 {} 启动。", new Object[] { LocalDateTime.now() }); + } + } + + @Override + public void schedulerStarting() { + if (this.logger.isDebugEnabled()) { + this.logger.debug("调度器启动中。", new Object[] { LocalDateTime.now() }); + } + } + + @Override + public void schedulerShutdown() { + if (this.logger.isDebugEnabled()) { + this.logger.debug("调度器 于 {} 关闭。", new Object[] { LocalDateTime.now() }); + } + } + + @Override + public void schedulerShuttingdown() { + if (this.logger.isDebugEnabled()) { + this.logger.debug("调度器关闭中。", new Object[] { LocalDateTime.now() }); + } + } + + @Override + public void schedulingDataCleared() { + if (this.logger.isDebugEnabled()) { + this.logger.debug("调度器于 {} 数据清空。", new Object[] { LocalDateTime.now() }); + } + } + +} diff --git a/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalTriggerListener.java b/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalTriggerListener.java index 82ce38b..f5ba209 100644 --- a/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalTriggerListener.java +++ b/src/main/java/com/xbd/quartz/listener/trigger/DefaultGlobalTriggerListener.java @@ -8,11 +8,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** - * * 默认全局TriggerListener - * * * @author 小不点 + * @since 1.0 */ public class DefaultGlobalTriggerListener extends AbstractTriggerListener { diff --git a/src/main/java/com/xbd/quartz/task/DemoTask.java b/src/test/java/com/xbd/quartz/task/DemoTask.java similarity index 98% rename from src/main/java/com/xbd/quartz/task/DemoTask.java rename to src/test/java/com/xbd/quartz/task/DemoTask.java index 08cac52..160588a 100644 --- a/src/main/java/com/xbd/quartz/task/DemoTask.java +++ b/src/test/java/com/xbd/quartz/task/DemoTask.java @@ -7,6 +7,7 @@ import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Component +@Deprecated public class DemoTask extends AbstractQuartzTask { private Logger logger = LoggerFactory.getLogger(getClass()); -- Gitee
* JobListener、SchedulerListener、TriggerListener自动注册监听 - *
此类已不再使用,请使用{@link QuartzJob}、{@link QuartzTrigger}组织定时任务. + * @author luas + * @since 1.0 + */ +@Deprecated public class QuartzTask implements Serializable { private String name; diff --git a/src/main/java/com/xbd/quartz/QuartzTaskHandler.java b/src/main/java/com/xbd/quartz/QuartzTaskHandler.java index 56d6f0c..73631fe 100644 --- a/src/main/java/com/xbd/quartz/QuartzTaskHandler.java +++ b/src/main/java/com/xbd/quartz/QuartzTaskHandler.java @@ -26,6 +26,152 @@ public abstract class QuartzTaskHandler { @NonNull protected Scheduler scheduler; + /** + * 动态添加任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void addTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量动态添加任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void addTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 动态更新任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void updateTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量动态更新任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void updateTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 暂停任务 + * + * @see QuartzTask + * + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void pauseTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量暂停任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void pauseTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 暂停所有任务 + * + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void pauseTask() throws SchedulerException; + + /** + * 继续任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void resumeTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量继续任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void resumeTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 删除任务 + * + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void deleteTask(QuartzTask quartzTask) throws SchedulerException; + + /** + * 批量删除任务 + * + * @see QuartzTask + * @param quartzTasks 定时任务信息集合 + * @throws SchedulerException + * @since 1.0 + */ + @Deprecated + public abstract void deleteTask(QuartzTask... quartzTasks) throws SchedulerException; + + /** + * 根据定时任务信息组织CronScheduleBuilder + * + * @see CronScheduleBuilder + * @see QuartzTask + * @param quartzTask 定时任务信息 + * @since 1.0 + */ + @Deprecated + public CronScheduleBuilder initCronScheduleBuilder(QuartzTask quartzTask) { + CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(quartzTask.getCronExpression()); + + // 以当前时间为触发频率立刻触发一次执行,然后按照Cron频率依次执行 + if (quartzTask.getMisfireInstruction() == CronTrigger.MISFIRE_INSTRUCTION_FIRE_ONCE_NOW) { + cronScheduleBuilder.withMisfireHandlingInstructionFireAndProceed(); + } else if (quartzTask.getMisfireInstruction() == CronTrigger.MISFIRE_INSTRUCTION_IGNORE_MISFIRE_POLICY) { + // 以错过的第一个频率时间立刻开始执行,重做错过的所有频率周期后,当下一次触发频率发生时间大于当前时间后,再按照正常的Cron频率依次执行 + cronScheduleBuilder.withMisfireHandlingInstructionIgnoreMisfires(); + } else if (quartzTask.getMisfireInstruction() == CronTrigger.MISFIRE_INSTRUCTION_DO_NOTHING) { + // 不触发立即执行,等待下次Cron触发频率到达时刻开始按照Cron频率依次执行 + cronScheduleBuilder.withMisfireHandlingInstructionDoNothing(); + } + + return cronScheduleBuilder; + } + /** * 动态添加任务 *
diff --git a/src/main/java/com/xbd/quartz/QuartzTriggerBuilder.java b/src/main/java/com/xbd/quartz/QuartzTriggerBuilder.java index a1b98b8..e37b7ec 100644 --- a/src/main/java/com/xbd/quartz/QuartzTriggerBuilder.java +++ b/src/main/java/com/xbd/quartz/QuartzTriggerBuilder.java @@ -7,6 +7,11 @@ import java.util.Date; import java.util.HashMap; import java.util.Map; +/** + * {@code QuartzTrigger} to {@link Trigger} + * @author luas + * @since 2.0 + */ public class QuartzTriggerBuilder { private QuartzTrigger.TriggerType type = QuartzTrigger.TriggerType.SIMPLE; diff --git a/src/main/java/com/xbd/quartz/configure/QuartzProperties.java b/src/main/java/com/xbd/quartz/configure/QuartzProperties.java index cb376ad..3b113c9 100644 --- a/src/main/java/com/xbd/quartz/configure/QuartzProperties.java +++ b/src/main/java/com/xbd/quartz/configure/QuartzProperties.java @@ -3,6 +3,10 @@ package com.xbd.quartz.configure; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.core.io.Resource; +/** + * @author luas + * @since 1.0 + */ @ConfigurationProperties(prefix = "sys.quartz") public class QuartzProperties { diff --git a/src/main/java/com/xbd/quartz/handler/DefaultQuartzTaskHandler.java b/src/main/java/com/xbd/quartz/handler/DefaultQuartzTaskHandler.java index db96f6e..3669e3d 100644 --- a/src/main/java/com/xbd/quartz/handler/DefaultQuartzTaskHandler.java +++ b/src/main/java/com/xbd/quartz/handler/DefaultQuartzTaskHandler.java @@ -5,39 +5,263 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.Stream; -import com.xbd.quartz.QuartzJob; -import com.xbd.quartz.QuartzTaskHandler; -import com.xbd.quartz.QuartzTrigger; +import com.xbd.quartz.*; import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.quartz.*; import org.quartz.impl.matchers.GroupMatcher; import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** - * QuartzTaskHandler的默认实现 - * + * {@code QuartzTaskHandler}的默认实现 + *
配置方式如下: *
- * SpringBoot项目 - * {@code @Bean} + * java配置: + * {@code + * @Bean * public DefaultQuartzTaskHandler defaultQuartzTaskHandler() { * DefaultQuartzTaskHandler defaultQuartzTaskHandler = new DefaultQuartzTaskHandler(); * defaultQuartzTaskHandler.setScheduler(scheduler); * return defaultQuartzTaskHandler; * } + * } * - * 同样也可以用在SpringMVC项目中: - * {@code } - * {@code } - * {@code } + * xml配置: + * {@code + * + * + * + * } *
- * 自定义JobListener,可匹配任务。定义并配置之后,系统可自动注册 - *
自定义JobListener,可匹配任务。定义并配置之后,系统可自动注册 * * @author 小不点 + * @since 1.0 */ public abstract class AbstractJobListener implements JobListener { + protected final Logger logger = LoggerFactory.getLogger(getClass()); + /** - *
* 返回匹配某一、某些Job的匹配策略 - *
* 自定义SchedulerListener。定义并配置之后,系统可自动注册 - *
* 自定义TriggerListener,可匹配任务。定义并配置之后,系统可自动注册 - *
* 返回匹配某一、某些Trigger的匹配策略 - *
* 默认全局TriggerListener - *