Skip to content

Commit

Permalink
feat($Quartz): add greeting Quartz job
Browse files Browse the repository at this point in the history
  • Loading branch information
johnnymillergh committed Jul 13, 2021
1 parent a52619c commit 7993f40
Show file tree
Hide file tree
Showing 5 changed files with 313 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -64,7 +65,8 @@
RabbitmqConfiguration.class,
MinioConfiguration.class,
JacksonConfiguration.class,
TypeConversionConfiguration.class
TypeConversionConfiguration.class,
QuartzConfiguration.class
})
public class MafAutoConfiguration {
@PostConstruct
Expand Down
Original file line number Diff line number Diff line change
@@ -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
* <a href='https://docs.spring.io/spring-boot/docs/current/reference/html/features.html#features.quartz'>Quartz Scheduler</a>
**/
@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());
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -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<String, Object> 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<String, Object> 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();
}
Original file line number Diff line number Diff line change
@@ -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 <a href='https://mp.weixin.qq.com/s/zJSPzcsFl72JNoqZpkH94A'>SpringBoot 整合 Quartz 实现分布式调度</a>
**/
@Slf4j
@RequiredArgsConstructor
public class QuartzJobServiceImpl implements QuartzJobService {
private final SchedulerFactoryBean schedulerFactoryBean;

@Override
public void addJob(String clazzName, String jobName, String groupName, String cronExp, Map<String, Object> 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<String, Object> 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);
}
}
}

0 comments on commit 7993f40

Please sign in to comment.