导入jar包
<!-- 分布式任务 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
<version>2.6.14</version>
</dependency>
QuartzJobFactory
/**
* 注册 Quartz 任务工厂
* 解决job中service注入为空的问题
*/
@Component
public class QuartzJobFactory extends AdaptableJobFactory {
@Resource
private AutowireCapableBeanFactory capableBeanFactory;
@Override
protected Object createJobInstance(TriggerFiredBundle bundle) throws Exception {
//调用父类的方法
Object jobInstance = super.createJobInstance(bundle);
//进行注入
capableBeanFactory.autowireBean(jobInstance);
return jobInstance;
}
}
QuartzConfig
/**
* 注册调度工厂, 使用spring默认的数据源, 只需将SchedulerFactoryBean注入就可
*/
@Configuration
public class QuartzConfig {
@Resource
private QuartzJobFactory quartzJobFactory;
@Bean
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) {
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setDataSource(dataSource);
// quartz 参数
Properties prop = new Properties();
prop.put("org.quartz.scheduler.instanceName", "SsmScheduler");
prop.put("org.quartz.scheduler.instanceId", "AUTO");
prop.put("org.quartz.scheduler.wrapJobExecutionInUserTransaction", "false"); //是否在Quartz执行一个job前使用UserTransaction
// 线程池的配置
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
prop.put("org.quartz.threadPool.threadCount", "20");
prop.put("org.quartz.threadPool.threadPriority", "5");
prop.put("org.quartz.threadPool.threadsInheritContextClassLoaderOfInitializingThread", "true"); // 配置是否启动自动加载数据库内的定时任务,默认true
prop.put("org.quartz.threadPool.makeThreadsDaemons", "true"); //是否设置为守护线程,设置后任务将不会执行
// JobStore配置
prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore");
// 集群配置
prop.put("org.quartz.jobStore.isClustered", "true");
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); //调度实例失效的检查时间间隔,单位毫秒
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
//mysql 数据库
prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.StdJDBCDelegate");
factory.setQuartzProperties(prop);
// 延时启动
factory.setStartupDelay(10);
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
factory.setJobFactory(quartzJobFactory);
// 这样当spring关闭时,会等待所有已经启动的quartz job结束后spring才能完全shutdown
factory.setWaitForJobsToCompleteOnShutdown(true);
// 是否覆盖己存在的Job
factory.setOverwriteExistingJobs(false);
return factory;
}
@Bean
public Scheduler scheduler(DataSource dataSource) {
return schedulerFactoryBean(dataSource).getScheduler();
}
}
表结构如下(常用表)
SELECT * from t_sox_schedule_log
SELECT * from qrtz_job_details
SELECT * from qrtz_triggers
SELECT * from qrtz_scheduler_state
开始/关闭任务方法
@Slf4j
@RestController
@RequestMapping("/sox-schedule-log")
@Api(tags = "定时任务查询控制器")
public class TSoxScheduleLogController {@Resource
private TSoxScheduleLogService tSoxScheduleLogService;
/**
* 开启一个分布式任务
* @return
*/
@ApiOperation(value = "开启一个分布式任务", notes = "开启一个分布式任务", httpMethod = "GET")
@GetMapping("/on/{id}")
public ReturnStruct on(@PathVariable String id) {
tSoxScheduleLogService.on(id);
return ReturnStruct.success();
}@ApiOperation(value = "关闭一个分布式任务", notes = "关闭一个分布式任务", httpMethod = "GET")
@GetMapping("/off/{id}")
public ReturnStruct off(@PathVariable String id) {
tSoxScheduleLogService.off(id);
return ReturnStruct.success();
}}
/**
* <p>
* 任务创建和执行信息 服务实现类
* </p>
*/
@Service
public class TSoxScheduleLogServiceImpl extends ServiceImpl<TSoxScheduleLogMapper, TSoxScheduleLog> implements TSoxScheduleLogService {@Resource
private QuartzJobService quartzJobService;@Override
public boolean on(String id) {
TSoxScheduleLog scheduleLog = this.baseMapper.selectById(id);
if(null == scheduleLog) {
throw new ResultEnumException("data_is_no_exist", new String[]{ id });
}
scheduleLog.setDelFlag(Constant.STR_0);
scheduleLog.setUpdateBy(ThreadLocalParams.LOGIN_MANAGER.get().getNo());
scheduleLog.setUpdateTime(LocalDateTime.now());
this.baseMapper.updateById(scheduleLog);
// 创建任务
QuartzConfigDTO quartzConfigDTO = new QuartzConfigDTO();
quartzConfigDTO.setJobName(scheduleLog.getTaskId());
quartzConfigDTO.setJobClass(scheduleLog.getExecBody()); // 实现类
if(StrUtil.isNotBlank(scheduleLog.getExecCron())) {
quartzConfigDTO.setCronExpression(scheduleLog.getExecCron());
quartzJobService.addCronJob(quartzConfigDTO);
}else if(null != scheduleLog.getExecTime()) {
quartzConfigDTO.setStartTime(new DateTime(scheduleLog.getExecTime()));
if(null != scheduleLog.getExecInterval()) {
quartzConfigDTO.setInterval(scheduleLog.getExecInterval());
}
quartzJobService.addSimpleJob(quartzConfigDTO);
}
return true;
}@Override
public boolean off(String id) {
TSoxScheduleLog scheduleLog = this.baseMapper.selectById(id);
if(null == scheduleLog) {
throw new ResultEnumException("data_is_no_exist", new String[]{ id });
}
scheduleLog.setDelFlag(Constant.STR_1);
scheduleLog.setUpdateBy(ThreadLocalParams.LOGIN_MANAGER.get().getNo());
scheduleLog.setUpdateTime(LocalDateTime.now());
this.baseMapper.updateById(scheduleLog);
// 删除任务
quartzJobService.deleteJob(scheduleLog.getTaskId(), null);
return true;
}
}
定时任务demo
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* 测试定时任务
*/
@Slf4j
@Component
public class TSoxTestJob extends QuartzJobBean {
@Autowired
private MailService mailService;
@Override
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
log.info("====================================== 测试任务开始");
log.info("====================================== 测试任务结束");
}
}
1277

被折叠的 条评论
为什么被折叠?



