diff --git a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/MafAutoConfiguration.java b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/MafAutoConfiguration.java
index dcca4ced..c9966e82 100644
--- a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/MafAutoConfiguration.java
+++ b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/MafAutoConfiguration.java
@@ -14,6 +14,7 @@
import com.jmsoftware.maf.springcloudstarter.helper.HttpApiScanHelper;
import com.jmsoftware.maf.springcloudstarter.helper.IpHelper;
import com.jmsoftware.maf.springcloudstarter.helper.SpringBootStartupHelper;
+import com.jmsoftware.maf.springcloudstarter.quartz.QuartzConfiguration;
import com.jmsoftware.maf.springcloudstarter.redis.RedisConfiguration;
import com.jmsoftware.maf.springcloudstarter.service.CommonService;
import com.jmsoftware.maf.springcloudstarter.service.impl.CommonServiceImpl;
@@ -64,7 +65,8 @@
RabbitmqConfiguration.class,
MinioConfiguration.class,
JacksonConfiguration.class,
- TypeConversionConfiguration.class
+ TypeConversionConfiguration.class,
+ QuartzConfiguration.class
})
public class MafAutoConfiguration {
@PostConstruct
diff --git a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/GreetingQuartzJobBean.java b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/GreetingQuartzJobBean.java
new file mode 100644
index 00000000..8f982aa0
--- /dev/null
+++ b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/GreetingQuartzJobBean.java
@@ -0,0 +1,29 @@
+package com.jmsoftware.maf.springcloudstarter.quartz;
+
+import com.jmsoftware.maf.springcloudstarter.configuration.MafProjectProperty;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.JobExecutionContext;
+import org.springframework.lang.NonNull;
+import org.springframework.scheduling.quartz.QuartzJobBean;
+
+/**
+ * Description: GreetingQuartzJobBean, change description here.
+ *
+ * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 7/13/2021 10:16 PM
+ * @see
+ * Quartz Scheduler
+ **/
+@Slf4j
+@RequiredArgsConstructor
+public class GreetingQuartzJobBean extends QuartzJobBean {
+ /**
+ * Injected field, spring bean.
+ */
+ private final MafProjectProperty mafProjectProperty;
+
+ @Override
+ protected void executeInternal(@NonNull JobExecutionContext jobExecutionContext) {
+ log.info("Greeting from Quartz job, current service is: {}", mafProjectProperty.getProjectArtifactId());
+ }
+}
diff --git a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/QuartzConfiguration.java b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/QuartzConfiguration.java
new file mode 100644
index 00000000..7bf35238
--- /dev/null
+++ b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/QuartzConfiguration.java
@@ -0,0 +1,55 @@
+package com.jmsoftware.maf.springcloudstarter.quartz;
+
+import com.jmsoftware.maf.springcloudstarter.configuration.MafProjectProperty;
+import lombok.val;
+import org.quartz.Scheduler;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.context.annotation.Bean;
+import org.springframework.scheduling.quartz.CronTriggerFactoryBean;
+import org.springframework.scheduling.quartz.JobDetailFactoryBean;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+import org.springframework.transaction.PlatformTransactionManager;
+
+import java.util.Optional;
+
+/**
+ * Description: QuartzConfiguration, change description here.
+ *
+ * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 7/13/2021 10:44 PM
+ **/
+@ConditionalOnClass({Scheduler.class, SchedulerFactoryBean.class, PlatformTransactionManager.class})
+public class QuartzConfiguration {
+ @Bean
+ public GreetingQuartzJobBean greetingQuartzJobBean(MafProjectProperty mafProjectProperty) {
+ return new GreetingQuartzJobBean(mafProjectProperty);
+ }
+
+ @Bean("greetingQuartzJobDetailFactoryBean")
+ public JobDetailFactoryBean greetingQuartzJobDetailFactoryBean(GreetingQuartzJobBean greetingQuartzJobBean) {
+ val jobDetailFactoryBean = new JobDetailFactoryBean();
+ jobDetailFactoryBean.setName("greeting-job-detail");
+ jobDetailFactoryBean.setGroup("default");
+ jobDetailFactoryBean.setJobClass(greetingQuartzJobBean.getClass());
+ jobDetailFactoryBean.setDescription("Greeting job detail created by JobDetailFactoryBean");
+ jobDetailFactoryBean.setDurability(true);
+ return jobDetailFactoryBean;
+ }
+
+ @Bean("greetingQuartzJobCronTriggerFactoryBean")
+ public CronTriggerFactoryBean greetingQuartzJobCronTriggerFactoryBean(
+ @Qualifier("greetingQuartzJobDetailFactoryBean") JobDetailFactoryBean jobDetailFactoryBean) {
+ val cronTriggerFactoryBean = new CronTriggerFactoryBean();
+ cronTriggerFactoryBean.setName("greeting-cron-trigger");
+ cronTriggerFactoryBean.setGroup("default");
+ cronTriggerFactoryBean.setCronExpression("0 0/1 * 1/1 * ? *");
+ val optionalJobDetail = Optional.ofNullable(jobDetailFactoryBean.getObject());
+ optionalJobDetail.ifPresent(cronTriggerFactoryBean::setJobDetail);
+ return cronTriggerFactoryBean;
+ }
+
+ @Bean
+ public QuartzJobService quartzJobService(SchedulerFactoryBean schedulerFactoryBean) {
+ return new QuartzJobServiceImpl(schedulerFactoryBean);
+ }
+}
diff --git a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/QuartzJobService.java b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/QuartzJobService.java
new file mode 100644
index 00000000..7d915f40
--- /dev/null
+++ b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/QuartzJobService.java
@@ -0,0 +1,83 @@
+package com.jmsoftware.maf.springcloudstarter.quartz;
+
+import java.util.Map;
+
+/**
+ * Description: QuartzJobService, change description here.
+ *
+ * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 7/13/2021 10:17 PM
+ */
+public interface QuartzJobService {
+ /**
+ * 添加任务可以传参数
+ *
+ * @param clazzName the clazz name
+ * @param jobName the job name
+ * @param groupName the group name
+ * @param cronExp the cron exp
+ * @param param the param
+ */
+ void addJob(String clazzName, String jobName, String groupName, String cronExp, Map param);
+
+ /**
+ * 暂停任务
+ *
+ * @param jobName the job name
+ * @param groupName the group name
+ */
+ void pauseJob(String jobName, String groupName);
+
+ /**
+ * 恢复任务
+ *
+ * @param jobName the job name
+ * @param groupName the group name
+ */
+ void resumeJob(String jobName, String groupName);
+
+ /**
+ * 立即运行一次定时任务
+ *
+ * @param jobName the job name
+ * @param groupName the group name
+ */
+ void runOnce(String jobName, String groupName);
+
+ /**
+ * 更新任务
+ *
+ * @param jobName the job name
+ * @param groupName the group name
+ * @param cronExp the cron exp
+ * @param param the param
+ */
+ void updateJob(String jobName, String groupName, String cronExp, Map param);
+
+ /**
+ * 删除任务
+ *
+ * @param jobName the job name
+ * @param groupName the group name
+ */
+ void deleteJob(String jobName, String groupName);
+
+ /**
+ * 启动所有任务
+ */
+ void startAllJobs();
+
+ /**
+ * 暂停所有任务
+ */
+ void pauseAllJobs();
+
+ /**
+ * 恢复所有任务
+ */
+ void resumeAllJobs();
+
+ /**
+ * 关闭所有任务
+ */
+ void shutdownAllJobs();
+}
diff --git a/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/QuartzJobServiceImpl.java b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/QuartzJobServiceImpl.java
new file mode 100644
index 00000000..dbf9c259
--- /dev/null
+++ b/spring-cloud-starter/src/main/java/com/jmsoftware/maf/springcloudstarter/quartz/QuartzJobServiceImpl.java
@@ -0,0 +1,143 @@
+package com.jmsoftware.maf.springcloudstarter.quartz;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.quartz.*;
+import org.springframework.scheduling.quartz.SchedulerFactoryBean;
+
+import java.util.Map;
+
+/**
+ * Description: QuartzJobServiceImpl, change description here.
+ *
+ * @author Johnny Miller (锺俊), email: johnnysviva@outlook.com, date: 7/13/2021 10:18 PM
+ * @see SpringBoot 整合 Quartz 实现分布式调度
+ **/
+@Slf4j
+@RequiredArgsConstructor
+public class QuartzJobServiceImpl implements QuartzJobService {
+ private final SchedulerFactoryBean schedulerFactoryBean;
+
+ @Override
+ public void addJob(String clazzName, String jobName, String groupName, String cronExp, Map param) {
+ try {
+ // 构建job信息
+ @SuppressWarnings("unchecked") Class extends Job> jobClass =
+ (Class extends Job>) Class.forName(clazzName);
+ JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, groupName).build();
+ // 表达式调度构建器(即任务执行的时间)
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExp);
+ // 按新的cronExpression表达式构建一个新的trigger
+ CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, groupName).withSchedule(
+ scheduleBuilder).build();
+ // 获得JobDataMap,写入数据
+ if (param != null) {
+ trigger.getJobDataMap().putAll(param);
+ }
+ schedulerFactoryBean.getScheduler().scheduleJob(jobDetail, trigger);
+ } catch (Exception e) {
+ log.error("创建任务失败", e);
+ }
+ }
+
+ @Override
+ public void pauseJob(String jobName, String groupName) {
+ try {
+ schedulerFactoryBean.getScheduler().pauseJob(JobKey.jobKey(jobName, groupName));
+ } catch (SchedulerException e) {
+ log.error("暂停任务失败", e);
+ }
+ }
+
+ @Override
+ public void resumeJob(String jobName, String groupName) {
+ try {
+ schedulerFactoryBean.getScheduler().resumeJob(JobKey.jobKey(jobName, groupName));
+ } catch (SchedulerException e) {
+ log.error("恢复任务失败", e);
+ }
+ }
+
+ @Override
+ public void runOnce(String jobName, String groupName) {
+ try {
+ schedulerFactoryBean.getScheduler().triggerJob(JobKey.jobKey(jobName, groupName));
+ } catch (SchedulerException e) {
+ log.error("立即运行一次定时任务失败", e);
+ }
+ }
+
+ @Override
+ public void updateJob(String jobName, String groupName, String cronExp, Map param) {
+ try {
+ TriggerKey triggerKey = TriggerKey.triggerKey(jobName, groupName);
+ CronTrigger trigger = (CronTrigger) schedulerFactoryBean.getScheduler().getTrigger(triggerKey);
+ if (cronExp != null) {
+ // 表达式调度构建器
+ CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExp);
+ // 按新的cronExpression表达式重新构建trigger
+ trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(scheduleBuilder).build();
+ }
+ //修改map
+ if (param != null) {
+ trigger.getJobDataMap().putAll(param);
+ }
+ // 按新的trigger重新设置job执行
+ schedulerFactoryBean.getScheduler().rescheduleJob(triggerKey, trigger);
+ } catch (Exception e) {
+ log.error("更新任务失败", e);
+ }
+ }
+
+ @Override
+ public void deleteJob(String jobName, String groupName) {
+ try {
+ //暂停、移除、删除
+ schedulerFactoryBean.getScheduler().pauseTrigger(TriggerKey.triggerKey(jobName, groupName));
+ schedulerFactoryBean.getScheduler().unscheduleJob(TriggerKey.triggerKey(jobName, groupName));
+ schedulerFactoryBean.getScheduler().deleteJob(JobKey.jobKey(jobName, groupName));
+ } catch (Exception e) {
+ log.error("删除任务失败", e);
+ }
+ }
+
+ @Override
+ public void startAllJobs() {
+ try {
+ schedulerFactoryBean.start();
+ } catch (Exception e) {
+ log.error("开启所有的任务失败", e);
+ }
+ }
+
+ @Override
+ public void pauseAllJobs() {
+ try {
+ schedulerFactoryBean.getScheduler().pauseAll();
+ } catch (Exception e) {
+ log.error("暂停所有任务失败", e);
+ }
+ }
+
+ @Override
+ public void resumeAllJobs() {
+ try {
+ schedulerFactoryBean.getScheduler().resumeAll();
+ } catch (Exception e) {
+ log.error("恢复所有任务失败", e);
+ }
+ }
+
+ @Override
+ public void shutdownAllJobs() {
+ try {
+ if (!schedulerFactoryBean.getScheduler().isShutdown()) {
+ // 需谨慎操作关闭scheduler容器
+ // scheduler生命周期结束,无法再 start() 启动 scheduler
+ schedulerFactoryBean.getScheduler().shutdown(true);
+ }
+ } catch (Exception e) {
+ log.error("关闭所有的任务失败", e);
+ }
+ }
+}