定时任务工具类
package com.ruoyi.project.wxb.utils;
import com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.common.exception.job.TaskException.Code;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.job.CronUtils;
import com.ruoyi.common.utils.job.QuartzDisallowConcurrentExecution;
import com.ruoyi.common.utils.job.QuartzJobExecution;
import com.ruoyi.project.monitor.domain.SysJob;
import org.quartz.*;
/**
* 定时任务工具类
*
*
*/
public class ScheduleUtil
{
/**
* 得到quartz任务类
*
* @param sysJob 执行计划
* @return 具体执行任务类
*/
private static Class<? extends Job> getQuartzJobClass(SysJob sysJob)
{
boolean isConcurrent = "0".equals(sysJob.getConcurrent());
return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class;
}
/**
* 构建任务触发对象
*/
public static TriggerKey getTriggerKey(Long jobId, String jobGroup)
{
return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
* 构建任务键对象
*/
public static JobKey getJobKey(Long jobId, String jobGroup)
{
return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
* 创建定时任务
*/
public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException
{
Class<? extends Job> jobClass = getQuartzJobClass(job);
// 构建job信息
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build();
// 表达式调度构建器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup))
.withSchedule(cronScheduleBuilder).build();
// 放入参数,运行时的方法可以获取
jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
// 判断是否存在
if (scheduler.checkExists(getJobKey(jobId, jobGroup)))
{
// 防止创建时存在数据问题 先移除,然后在执行创建操作
scheduler.deleteJob(getJobKey(jobId, jobGroup));
}
// 暂停任务
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
{
scheduler.pauseJob(ScheduleUtil.getJobKey(jobId, jobGroup));
}
// 判断任务是否过期
if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression())))
{
// 执行调度任务
scheduler.scheduleJob(jobDetail, trigger);
}
}
/**
* 设置定时任务策略
*/
public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb)
throws TaskException
{
switch (job.getMisfirePolicy())
{
case ScheduleConstants.MISFIRE_DEFAULT:
return cb;
case ScheduleConstants.MISFIRE_IGNORE_MISFIRES:
return cb.withMisfireHandlingInstructionIgnoreMisfires();
case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED:
return cb.withMisfireHandlingInstructionFireAndProceed();
case ScheduleConstants.MISFIRE_DO_NOTHING:
return cb.withMisfireHandlingInstructionDoNothing();
default:
throw new TaskException("The task misfire policy '" + job.getMisfirePolicy()
+ "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR);
}
}
}
所需实体类
package com.ruoyi.project.monitor.domain;
import java.util.Date;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.constant.ScheduleConstants;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.job.CronUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.aspectj.lang.annotation.Excel.ColumnType;
import com.ruoyi.framework.web.domain.BaseEntity;
/**
* 定时任务调度表 sys_job
*
* @author ruoyi
*/
public class SysJob extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 任务ID */
@Excel(name = "任务序号", cellType = ColumnType.NUMERIC)
private Long jobId;
/** 任务名称 */
@Excel(name = "任务名称")
private String jobName;
/** 任务组名 */
@Excel(name = "任务组名")
private String jobGroup;
/** 调用目标字符串 */
@Excel(name = "调用目标字符串")
private String invokeTarget;
/** cron执行表达式 */
@Excel(name = "执行表达式 ")
private String cronExpression;
/** cron计划策略 */
@Excel(name = "计划策略 ", readConverterExp = "0=默认,1=立即触发执行,2=触发一次执行,3=不触发立即执行")
private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT;
/** 是否并发执行(0允许 1禁止) */
@Excel(name = "并发执行", readConverterExp = "0=允许,1=禁止")
private String concurrent;
/** 任务状态(0正常 1暂停) */
@Excel(name = "任务状态", readConverterExp = "0=正常,1=暂停")
private String status;
public Long getJobId()
{
return jobId;
}
public void setJobId(Long jobId)
{
this.jobId = jobId;
}
@NotBlank(message = "任务名称不能为空")
@Size(min = 0, max = 64, message = "任务名称不能超过64个字符")
public String getJobName()
{
return jobName;
}
public void setJobName(String jobName)
{
this.jobName = jobName;
}
public String getJobGroup()
{
return jobGroup;
}
public void setJobGroup(String jobGroup)
{
this.jobGroup = jobGroup;
}
@NotBlank(message = "调用目标字符串不能为空")
@Size(min = 0, max = 500, message = "调用目标字符串长度不能超过500个字符")
public String getInvokeTarget()
{
return invokeTarget;
}
public void setInvokeTarget(String invokeTarget)
{
this.invokeTarget = invokeTarget;
}
@NotBlank(message = "Cron执行表达式不能为空")
@Size(min = 0, max = 255, message = "Cron执行表达式不能超过255个字符")
public String getCronExpression()
{
return cronExpression;
}
public void setCronExpression(String cronExpression)
{
this.cronExpression = cronExpression;
}
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
public Date getNextValidTime()
{
if (StringUtils.isNotEmpty(cronExpression))
{
return CronUtils.getNextExecution(cronExpression);
}
return null;
}
public String getMisfirePolicy()
{
return misfirePolicy;
}
public void setMisfirePolicy(String misfirePolicy)
{
this.misfirePolicy = misfirePolicy;
}
public String getConcurrent()
{
return concurrent;
}
public void setConcurrent(String concurrent)
{
this.concurrent = concurrent;
}
public String getStatus()
{
return status;
}
public void setStatus(String status)
{
this.status = status;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("jobId", getJobId())
.append("jobName", getJobName())
.append("jobGroup", getJobGroup())
.append("cronExpression", getCronExpression())
.append("nextValidTime", getNextValidTime())
.append("misfirePolicy", getMisfirePolicy())
.append("concurrent", getConcurrent())
.append("status", getStatus())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime())
.append("remark", getRemark())
.toString();
}
}
Scheduler是quartz包里面的,导入pom即可
<!--引入quartz依赖-->
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>2.2.1</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-jobs</artifactId>
<version>2.2.1</version>
</dependency>
数据库信息
多个参数逗号隔开
Cron表达式工具
@Component
public class CronUtil {
// 每天执行
private static final String DATE_FORMAT_EVERY_DAY = "ss mm HH * * ?";
// 转换每天执行的cron表达式
public static String getCronForEveryDay(String dateStr){
SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT_EVERY_DAY);
SimpleDateFormat sdfInput = new SimpleDateFormat("HH:mm:ss");
String cron = "error";
try{
Date date = sdfInput.parse(dateStr);
cron = sdf.format(date);
}catch (Exception e){
e.printStackTrace();
}
return cron;
}
}
service代码,mapper指向上文的数据库
package com.ruoyi.project.wxb.service.impl;
import com.ruoyi.common.exception.job.TaskException;
import com.ruoyi.common.utils.job.ScheduleUtils;
import com.ruoyi.project.monitor.domain.SysJob;
import com.ruoyi.project.wxb.entity.vo.R;
import com.ruoyi.project.wxb.mapper.QuartzMapper;
import com.ruoyi.project.wxb.service.QuartzService;
import com.ruoyi.project.wxb.utils.CronUtil;
import com.ruoyi.project.wxb.utils.ScheduleUtil;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.List;
@Service
public class QuartzServiceImpl implements QuartzService {
@Autowired
private QuartzMapper quartzMapper;
@Autowired
private Scheduler scheduler;
public void init() throws SchedulerException, TaskException {
scheduler.clear();
List<SysJob> jobList = quartzMapper.getJobList();
for (SysJob job : jobList) {
ScheduleUtil.createScheduleJob(scheduler, job);
}
}
@Override
public R addJob(String jobId, String time, String invokeTarget, String name, String group) {
try{
SysJob sysJob = new SysJob();
sysJob.setJobId(Long.valueOf(jobId));
sysJob.setCronExpression(CronUtil.getCronForEveryDay(time));
sysJob.setInvokeTarget(invokeTarget);
sysJob.setJobName(name);
sysJob.setJobGroup(group);
quartzMapper.addJob(sysJob);
return R.ok();
}catch (Exception e){
e.printStackTrace();
return R.fail("插入Job失败!");
}
}
@Override
public void deleteJobs(List<Long> jobIdList) {
quartzMapper.deleteJobs(jobIdList);
}
@Override
public void updateJob(String startTime, String jobId) {
String cron = CronUtil.getCronForEveryDay(startTime);
quartzMapper.updateJob(cron,jobId);
}
}
定时执行
@Configuration
@EnableScheduling
@Slf4j
public class JobSchedule {
@Autowired
private QuartzServiceImpl quartzService;
//每天扫描一次
@Scheduled(cron = "0 0 0 */1 * ?")
private void carDefendTask() {
log.info("JobSchedule start 启动 :" + System.currentTimeMillis());
try {
quartzService.init();
} catch (Exception e) {
e.printStackTrace();
log.info("JobSchedule error :" + System.currentTimeMillis()+"========="+e.getMessage());
}
log.info("JobSchedule end 结束 :" + System.currentTimeMillis());
}
}
如果上述代码正确可以运行,这里的意思就是,定时执行ryTask里的ryNoParams方法,或执行ryParams方法,其参数为(‘ry’),可能需要在ryTask方法上添加@Service(”ryTask“)或者@Component(”ryTask“)
例如
版权声明:本文为weixin_59499726原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。