若依 3.0
This commit is contained in:
@ -0,0 +1,58 @@
|
||||
package com.ruoyi.quartz.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
|
||||
import javax.sql.DataSource;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
* 定时任务配置
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
public class ScheduleConfig
|
||||
{
|
||||
@Bean
|
||||
public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource)
|
||||
{
|
||||
SchedulerFactoryBean factory = new SchedulerFactoryBean();
|
||||
factory.setDataSource(dataSource);
|
||||
|
||||
// quartz参数
|
||||
Properties prop = new Properties();
|
||||
prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler");
|
||||
prop.put("org.quartz.scheduler.instanceId", "AUTO");
|
||||
// 线程池配置
|
||||
prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool");
|
||||
prop.put("org.quartz.threadPool.threadCount", "20");
|
||||
prop.put("org.quartz.threadPool.threadPriority", "5");
|
||||
// JobStore配置
|
||||
prop.put("org.quartz.jobStore.class", "org.quartz.impl.jdbcjobstore.JobStoreTX");
|
||||
// 集群配置
|
||||
prop.put("org.quartz.jobStore.isClustered", "true");
|
||||
prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
|
||||
prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
|
||||
prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
|
||||
|
||||
// sqlserver 启用
|
||||
// prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?");
|
||||
prop.put("org.quartz.jobStore.misfireThreshold", "12000");
|
||||
prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_");
|
||||
factory.setQuartzProperties(prop);
|
||||
|
||||
factory.setSchedulerName("RuoyiScheduler");
|
||||
// 延时启动
|
||||
factory.setStartupDelay(1);
|
||||
factory.setApplicationContextSchedulerContextKey("applicationContextKey");
|
||||
// 可选,QuartzScheduler
|
||||
// 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了
|
||||
factory.setOverwriteExistingJobs(true);
|
||||
// 设置自动启动,默认为true
|
||||
factory.setAutoStartup(true);
|
||||
|
||||
return factory;
|
||||
}
|
||||
}
|
149
ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java
Normal file
149
ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java
Normal file
@ -0,0 +1,149 @@
|
||||
package com.ruoyi.quartz.domain;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import java.io.Serializable;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.base.BaseEntity;
|
||||
import com.ruoyi.common.constant.ScheduleConstants;
|
||||
|
||||
/**
|
||||
* 定时任务调度表 sys_job
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysJob extends BaseEntity implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 任务ID */
|
||||
@Excel(name = "任务序号")
|
||||
private Long jobId;
|
||||
|
||||
/** 任务名称 */
|
||||
@Excel(name = "任务名称")
|
||||
private String jobName;
|
||||
|
||||
/** 任务组名 */
|
||||
@Excel(name = "任务组名")
|
||||
private String jobGroup;
|
||||
|
||||
/** 任务方法 */
|
||||
@Excel(name = "任务方法")
|
||||
private String methodName;
|
||||
|
||||
/** 方法参数 */
|
||||
@Excel(name = "方法参数")
|
||||
private String methodParams;
|
||||
|
||||
/** cron执行表达式 */
|
||||
@Excel(name = "执行表达式 ")
|
||||
private String cronExpression;
|
||||
|
||||
/** cron计划策略 */
|
||||
@Excel(name = "计划策略 ")
|
||||
private String misfirePolicy = ScheduleConstants.MISFIRE_DEFAULT;
|
||||
|
||||
/** 任务状态(0正常 1暂停) */
|
||||
@Excel(name = "任务状态")
|
||||
private String status;
|
||||
|
||||
public Long getJobId()
|
||||
{
|
||||
return jobId;
|
||||
}
|
||||
|
||||
public void setJobId(Long jobId)
|
||||
{
|
||||
this.jobId = jobId;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public String getMethodName()
|
||||
{
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName)
|
||||
{
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
public String getMethodParams()
|
||||
{
|
||||
return methodParams;
|
||||
}
|
||||
|
||||
public void setMethodParams(String methodParams)
|
||||
{
|
||||
this.methodParams = methodParams;
|
||||
}
|
||||
|
||||
public String getCronExpression()
|
||||
{
|
||||
return cronExpression;
|
||||
}
|
||||
|
||||
public void setCronExpression(String cronExpression)
|
||||
{
|
||||
this.cronExpression = cronExpression;
|
||||
}
|
||||
|
||||
public String getMisfirePolicy()
|
||||
{
|
||||
return misfirePolicy;
|
||||
}
|
||||
|
||||
public void setMisfirePolicy(String misfirePolicy)
|
||||
{
|
||||
this.misfirePolicy = misfirePolicy;
|
||||
}
|
||||
|
||||
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("methodName", getMethodName())
|
||||
.append("methodParams", getMethodParams())
|
||||
.append("cronExpression", getCronExpression())
|
||||
.append("misfirePolicy", getMisfirePolicy())
|
||||
.append("status", getStatus())
|
||||
.append("createBy", getCreateBy())
|
||||
.append("createTime", getCreateTime())
|
||||
.append("updateBy", getUpdateBy())
|
||||
.append("updateTime", getUpdateTime())
|
||||
.append("remark", getRemark())
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,143 @@
|
||||
package com.ruoyi.quartz.domain;
|
||||
|
||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||
import com.ruoyi.common.annotation.Excel;
|
||||
import com.ruoyi.common.base.BaseEntity;
|
||||
|
||||
/**
|
||||
* 定时任务调度日志表 sys_job_log
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class SysJobLog extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** ID */
|
||||
@Excel(name = "日志序号")
|
||||
private Long jobLogId;
|
||||
|
||||
/** 任务名称 */
|
||||
@Excel(name = "任务名称")
|
||||
private String jobName;
|
||||
|
||||
/** 任务组名 */
|
||||
@Excel(name = "任务组名")
|
||||
private String jobGroup;
|
||||
|
||||
/** 任务方法 */
|
||||
@Excel(name = "任务方法")
|
||||
private String methodName;
|
||||
|
||||
/** 方法参数 */
|
||||
@Excel(name = "方法参数")
|
||||
private String methodParams;
|
||||
|
||||
/** 日志信息 */
|
||||
@Excel(name = "日志信息")
|
||||
private String jobMessage;
|
||||
|
||||
/** 执行状态(0正常 1失败) */
|
||||
@Excel(name = "执行状态")
|
||||
private String status;
|
||||
|
||||
/** 异常信息 */
|
||||
@Excel(name = "异常信息")
|
||||
private String exceptionInfo;
|
||||
|
||||
public Long getJobLogId()
|
||||
{
|
||||
return jobLogId;
|
||||
}
|
||||
|
||||
public void setJobLogId(Long jobLogId)
|
||||
{
|
||||
this.jobLogId = jobLogId;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public String getMethodName()
|
||||
{
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public void setMethodName(String methodName)
|
||||
{
|
||||
this.methodName = methodName;
|
||||
}
|
||||
|
||||
public String getMethodParams()
|
||||
{
|
||||
return methodParams;
|
||||
}
|
||||
|
||||
public void setMethodParams(String methodParams)
|
||||
{
|
||||
this.methodParams = methodParams;
|
||||
}
|
||||
|
||||
public String getJobMessage()
|
||||
{
|
||||
return jobMessage;
|
||||
}
|
||||
|
||||
public void setJobMessage(String jobMessage)
|
||||
{
|
||||
this.jobMessage = jobMessage;
|
||||
}
|
||||
|
||||
public String getStatus()
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status)
|
||||
{
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getExceptionInfo()
|
||||
{
|
||||
return exceptionInfo;
|
||||
}
|
||||
|
||||
public void setExceptionInfo(String exceptionInfo)
|
||||
{
|
||||
this.exceptionInfo = exceptionInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||
.append("jobLogId", getJobLogId())
|
||||
.append("jobName", getJobName())
|
||||
.append("jobGroup", getJobGroup())
|
||||
.append("methodName", getMethodName())
|
||||
.append("methodParams", getMethodParams())
|
||||
.append("jobMessage", getJobMessage())
|
||||
.append("status", getStatus())
|
||||
.append("exceptionInfo", getExceptionInfo())
|
||||
.append("createTime", getCreateTime())
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -0,0 +1,57 @@
|
||||
package com.ruoyi.quartz.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.quartz.domain.SysJobLog;
|
||||
|
||||
/**
|
||||
* 调度任务日志信息 数据层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface SysJobLogMapper
|
||||
{
|
||||
/**
|
||||
* 获取quartz调度器日志的计划任务
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
* @return 调度任务日志集合
|
||||
*/
|
||||
public List<SysJobLog> selectJobLogList(SysJobLog jobLog);
|
||||
|
||||
/**
|
||||
* 通过调度任务日志ID查询调度信息
|
||||
*
|
||||
* @param jobLogId 调度任务日志ID
|
||||
* @return 调度任务日志对象信息
|
||||
*/
|
||||
public SysJobLog selectJobLogById(Long jobLogId);
|
||||
|
||||
/**
|
||||
* 新增任务日志
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertJobLog(SysJobLog jobLog);
|
||||
|
||||
/**
|
||||
* 批量删除调度日志信息
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobLogByIds(String[] ids);
|
||||
|
||||
/**
|
||||
* 删除任务日志
|
||||
*
|
||||
* @param jobId 调度日志ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobLogById(Long jobId);
|
||||
|
||||
/**
|
||||
* 清空任务日志
|
||||
*/
|
||||
public void cleanJobLog();
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
package com.ruoyi.quartz.mapper;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.quartz.domain.SysJob;
|
||||
|
||||
/**
|
||||
* 调度任务信息 数据层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface SysJobMapper
|
||||
{
|
||||
/**
|
||||
* 查询调度任务日志集合
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 操作日志集合
|
||||
*/
|
||||
public List<SysJob> selectJobList(SysJob job);
|
||||
|
||||
/**
|
||||
* 查询所有调度任务
|
||||
*
|
||||
* @return 调度任务列表
|
||||
*/
|
||||
public List<SysJob> selectJobAll();
|
||||
|
||||
/**
|
||||
* 通过调度ID查询调度任务信息
|
||||
*
|
||||
* @param jobId 调度ID
|
||||
* @return 角色对象信息
|
||||
*/
|
||||
public SysJob selectJobById(Long jobId);
|
||||
|
||||
/**
|
||||
* 通过调度ID删除调度任务信息
|
||||
*
|
||||
* @param jobId 调度ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobById(SysJob job);
|
||||
|
||||
/**
|
||||
* 批量删除调度任务信息
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobLogByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 修改调度任务信息
|
||||
*
|
||||
* @param job 调度任务信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateJob(SysJob job);
|
||||
|
||||
/**
|
||||
* 新增调度任务信息
|
||||
*
|
||||
* @param job 调度任务信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertJob(SysJob job);
|
||||
}
|
@ -0,0 +1,56 @@
|
||||
package com.ruoyi.quartz.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.quartz.domain.SysJobLog;
|
||||
|
||||
/**
|
||||
* 定时任务调度日志信息信息 服务层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ISysJobLogService
|
||||
{
|
||||
/**
|
||||
* 获取quartz调度器日志的计划任务
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
* @return 调度任务日志集合
|
||||
*/
|
||||
public List<SysJobLog> selectJobLogList(SysJobLog jobLog);
|
||||
|
||||
/**
|
||||
* 通过调度任务日志ID查询调度信息
|
||||
*
|
||||
* @param jobLogId 调度任务日志ID
|
||||
* @return 调度任务日志对象信息
|
||||
*/
|
||||
public SysJobLog selectJobLogById(Long jobLogId);
|
||||
|
||||
/**
|
||||
* 新增任务日志
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
*/
|
||||
public void addJobLog(SysJobLog jobLog);
|
||||
|
||||
/**
|
||||
* 批量删除调度日志信息
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobLogByIds(String ids);
|
||||
|
||||
/**
|
||||
* 删除任务日志
|
||||
*
|
||||
* @param jobId 调度日志ID
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJobLogById(Long jobId);
|
||||
|
||||
/**
|
||||
* 清空任务日志
|
||||
*/
|
||||
public void cleanJobLog();
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
package com.ruoyi.quartz.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.ruoyi.quartz.domain.SysJob;
|
||||
|
||||
/**
|
||||
* 定时任务调度信息信息 服务层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public interface ISysJobService
|
||||
{
|
||||
/**
|
||||
* 获取quartz调度器的计划任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 调度任务集合
|
||||
*/
|
||||
public List<SysJob> selectJobList(SysJob job);
|
||||
|
||||
/**
|
||||
* 通过调度任务ID查询调度信息
|
||||
*
|
||||
* @param jobId 调度任务ID
|
||||
* @return 调度任务对象信息
|
||||
*/
|
||||
public SysJob selectJobById(Long jobId);
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int pauseJob(SysJob job);
|
||||
|
||||
/**
|
||||
* 恢复任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int resumeJob(SysJob job);
|
||||
|
||||
/**
|
||||
* 删除任务后,所对应的trigger也将被删除
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteJob(SysJob job);
|
||||
|
||||
/**
|
||||
* 批量删除调度信息
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
public void deleteJobByIds(String ids);
|
||||
|
||||
/**
|
||||
* 任务调度状态修改
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int changeStatus(SysJob job);
|
||||
|
||||
/**
|
||||
* 立即运行任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int run(SysJob job);
|
||||
|
||||
/**
|
||||
* 新增任务表达式
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertJobCron(SysJob job);
|
||||
|
||||
/**
|
||||
* 更新任务的时间表达式
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateJobCron(SysJob job);
|
||||
}
|
@ -0,0 +1,88 @@
|
||||
package com.ruoyi.quartz.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.common.support.Convert;
|
||||
import com.ruoyi.quartz.domain.SysJobLog;
|
||||
import com.ruoyi.quartz.mapper.SysJobLogMapper;
|
||||
import com.ruoyi.quartz.service.ISysJobLogService;
|
||||
|
||||
/**
|
||||
* 定时任务调度日志信息 服务层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class SysJobLogServiceImpl implements ISysJobLogService
|
||||
{
|
||||
@Autowired
|
||||
private SysJobLogMapper jobLogMapper;
|
||||
|
||||
/**
|
||||
* 获取quartz调度器日志的计划任务
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
* @return 调度任务日志集合
|
||||
*/
|
||||
@Override
|
||||
public List<SysJobLog> selectJobLogList(SysJobLog jobLog)
|
||||
{
|
||||
return jobLogMapper.selectJobLogList(jobLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过调度任务日志ID查询调度信息
|
||||
*
|
||||
* @param jobId 调度任务日志ID
|
||||
* @return 调度任务日志对象信息
|
||||
*/
|
||||
@Override
|
||||
public SysJobLog selectJobLogById(Long jobLogId)
|
||||
{
|
||||
return jobLogMapper.selectJobLogById(jobLogId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增任务日志
|
||||
*
|
||||
* @param jobLog 调度日志信息
|
||||
*/
|
||||
@Override
|
||||
public void addJobLog(SysJobLog jobLog)
|
||||
{
|
||||
jobLogMapper.insertJobLog(jobLog);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除调度日志信息
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteJobLogByIds(String ids)
|
||||
{
|
||||
return jobLogMapper.deleteJobLogByIds(Convert.toStrArray(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务日志
|
||||
*
|
||||
* @param jobId 调度日志ID
|
||||
*/
|
||||
@Override
|
||||
public int deleteJobLogById(Long jobId)
|
||||
{
|
||||
return jobLogMapper.deleteJobLogById(jobId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空任务日志
|
||||
*/
|
||||
@Override
|
||||
public void cleanJobLog()
|
||||
{
|
||||
jobLogMapper.cleanJobLog();
|
||||
}
|
||||
}
|
@ -0,0 +1,207 @@
|
||||
package com.ruoyi.quartz.service.impl;
|
||||
|
||||
import java.util.List;
|
||||
import javax.annotation.PostConstruct;
|
||||
import org.quartz.CronTrigger;
|
||||
import org.quartz.Scheduler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.ruoyi.common.constant.ScheduleConstants;
|
||||
import com.ruoyi.common.support.Convert;
|
||||
import com.ruoyi.quartz.domain.SysJob;
|
||||
import com.ruoyi.quartz.mapper.SysJobMapper;
|
||||
import com.ruoyi.quartz.service.ISysJobService;
|
||||
import com.ruoyi.quartz.util.ScheduleUtils;
|
||||
|
||||
/**
|
||||
* 定时任务调度信息 服务层
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Service
|
||||
public class SysJobServiceImpl implements ISysJobService
|
||||
{
|
||||
@Autowired
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Autowired
|
||||
private SysJobMapper jobMapper;
|
||||
|
||||
/**
|
||||
* 项目启动时,初始化定时器
|
||||
*/
|
||||
@PostConstruct
|
||||
public void init()
|
||||
{
|
||||
List<SysJob> jobList = jobMapper.selectJobAll();
|
||||
for (SysJob job : jobList)
|
||||
{
|
||||
CronTrigger cronTrigger = ScheduleUtils.getCronTrigger(scheduler, job.getJobId());
|
||||
// 如果不存在,则创建
|
||||
if (cronTrigger == null)
|
||||
{
|
||||
ScheduleUtils.createScheduleJob(scheduler, job);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScheduleUtils.updateScheduleJob(scheduler, job);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取quartz调度器的计划任务列表
|
||||
*
|
||||
* @param job 调度信息
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public List<SysJob> selectJobList(SysJob job)
|
||||
{
|
||||
return jobMapper.selectJobList(job);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过调度任务ID查询调度信息
|
||||
*
|
||||
* @param jobId 调度任务ID
|
||||
* @return 调度任务对象信息
|
||||
*/
|
||||
@Override
|
||||
public SysJob selectJobById(Long jobId)
|
||||
{
|
||||
return jobMapper.selectJobById(jobId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
public int pauseJob(SysJob job)
|
||||
{
|
||||
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
|
||||
int rows = jobMapper.updateJob(job);
|
||||
if (rows > 0)
|
||||
{
|
||||
ScheduleUtils.pauseJob(scheduler, job.getJobId());
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
public int resumeJob(SysJob job)
|
||||
{
|
||||
job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
|
||||
int rows = jobMapper.updateJob(job);
|
||||
if (rows > 0)
|
||||
{
|
||||
ScheduleUtils.resumeJob(scheduler, job.getJobId());
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除任务后,所对应的trigger也将被删除
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
public int deleteJob(SysJob job)
|
||||
{
|
||||
int rows = jobMapper.deleteJobById(job);
|
||||
if (rows > 0)
|
||||
{
|
||||
ScheduleUtils.deleteScheduleJob(scheduler, job.getJobId());
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除调度信息
|
||||
*
|
||||
* @param ids 需要删除的数据ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public void deleteJobByIds(String ids)
|
||||
{
|
||||
Long[] jobIds = Convert.toLongArray(ids);
|
||||
for (Long jobId : jobIds)
|
||||
{
|
||||
SysJob job = jobMapper.selectJobById(jobId);
|
||||
deleteJob(job);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务调度状态修改
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
public int changeStatus(SysJob job)
|
||||
{
|
||||
int rows = 0;
|
||||
String status = job.getStatus();
|
||||
if (ScheduleConstants.Status.NORMAL.getValue().equals(status))
|
||||
{
|
||||
rows = resumeJob(job);
|
||||
}
|
||||
else if (ScheduleConstants.Status.PAUSE.getValue().equals(status))
|
||||
{
|
||||
rows = pauseJob(job);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即运行任务
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
public int run(SysJob job)
|
||||
{
|
||||
return ScheduleUtils.run(scheduler, selectJobById(job.getJobId()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增任务
|
||||
*
|
||||
* @param job 调度信息 调度信息
|
||||
*/
|
||||
@Override
|
||||
public int insertJobCron(SysJob job)
|
||||
{
|
||||
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
|
||||
int rows = jobMapper.insertJob(job);
|
||||
if (rows > 0)
|
||||
{
|
||||
ScheduleUtils.createScheduleJob(scheduler, job);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新任务的时间表达式
|
||||
*
|
||||
* @param job 调度信息
|
||||
*/
|
||||
@Override
|
||||
public int updateJobCron(SysJob job)
|
||||
{
|
||||
int rows = jobMapper.updateJob(job);
|
||||
if (rows > 0)
|
||||
{
|
||||
ScheduleUtils.updateScheduleJob(scheduler, job);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
}
|
22
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
Normal file
22
ruoyi-quartz/src/main/java/com/ruoyi/quartz/task/RyTask.java
Normal file
@ -0,0 +1,22 @@
|
||||
package com.ruoyi.quartz.task;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 定时任务调度测试
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component("ryTask")
|
||||
public class RyTask
|
||||
{
|
||||
public void ryParams(String params)
|
||||
{
|
||||
System.out.println("执行有参方法:" + params);
|
||||
}
|
||||
|
||||
public void ryNoParams()
|
||||
{
|
||||
System.out.println("执行无参方法");
|
||||
}
|
||||
}
|
@ -0,0 +1,77 @@
|
||||
package com.ruoyi.quartz.util;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.Future;
|
||||
import org.quartz.JobExecutionContext;
|
||||
import org.quartz.JobExecutionException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.scheduling.quartz.QuartzJobBean;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.constant.ScheduleConstants;
|
||||
import com.ruoyi.common.utils.bean.BeanUtils;
|
||||
import com.ruoyi.quartz.domain.SysJob;
|
||||
import com.ruoyi.quartz.domain.SysJobLog;
|
||||
import com.ruoyi.quartz.service.ISysJobLogService;
|
||||
|
||||
/**
|
||||
* 定时任务处理
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
public class ScheduleJob extends QuartzJobBean
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(ScheduleJob.class);
|
||||
|
||||
private ExecutorService service = Executors.newSingleThreadExecutor();
|
||||
|
||||
private final static ISysJobLogService jobLogService = (ISysJobLogService) SpringContextUtil.getBean("sysJobLogServiceImpl");
|
||||
|
||||
@Override
|
||||
protected void executeInternal(JobExecutionContext context) throws JobExecutionException
|
||||
{
|
||||
SysJob job = new SysJob();
|
||||
BeanUtils.copyBeanProp(job, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
|
||||
|
||||
SysJobLog jobLog = new SysJobLog();
|
||||
jobLog.setJobName(job.getJobName());
|
||||
jobLog.setJobGroup(job.getJobGroup());
|
||||
jobLog.setMethodName(job.getMethodName());
|
||||
jobLog.setMethodParams(job.getMethodParams());
|
||||
jobLog.setCreateTime(new Date());
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
try
|
||||
{
|
||||
// 执行任务
|
||||
log.info("任务开始执行 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
|
||||
ScheduleRunnable task = new ScheduleRunnable(job.getJobName(), job.getMethodName(), job.getMethodParams());
|
||||
Future<?> future = service.submit(task);
|
||||
future.get();
|
||||
long times = System.currentTimeMillis() - startTime;
|
||||
// 任务状态 0:成功 1:失败
|
||||
jobLog.setStatus(Constants.SUCCESS);
|
||||
jobLog.setJobMessage(job.getJobName() + " 总共耗时:" + times + "毫秒");
|
||||
|
||||
log.info("任务执行结束 - 名称:{} 耗时:{} 毫秒", job.getJobName(), times);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.info("任务执行失败 - 名称:{} 方法:{}", job.getJobName(), job.getMethodName());
|
||||
log.error("任务执行异常 - :", e);
|
||||
long times = System.currentTimeMillis() - startTime;
|
||||
jobLog.setJobMessage(job.getJobName() + " 总共耗时:" + times + "毫秒");
|
||||
// 任务状态 0:成功 1:失败
|
||||
jobLog.setStatus(Constants.FAIL);
|
||||
jobLog.setExceptionInfo(e.toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
jobLogService.addJobLog(jobLog);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
package com.ruoyi.quartz.util;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 执行定时任务
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
public class ScheduleRunnable implements Runnable
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(ScheduleRunnable.class);
|
||||
|
||||
private Object target;
|
||||
private Method method;
|
||||
private String params;
|
||||
|
||||
public ScheduleRunnable(String beanName, String methodName, String params)
|
||||
throws NoSuchMethodException, SecurityException
|
||||
{
|
||||
this.target = SpringContextUtil.getBean(beanName);
|
||||
this.params = params;
|
||||
|
||||
if (StringUtils.isNotEmpty(params))
|
||||
{
|
||||
this.method = target.getClass().getDeclaredMethod(methodName, String.class);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.method = target.getClass().getDeclaredMethod(methodName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
ReflectionUtils.makeAccessible(method);
|
||||
if (StringUtils.isNotEmpty(params))
|
||||
{
|
||||
method.invoke(target, params);
|
||||
}
|
||||
else
|
||||
{
|
||||
method.invoke(target);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("执行定时任务 - :", e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,225 @@
|
||||
package com.ruoyi.quartz.util;
|
||||
|
||||
import org.quartz.CronScheduleBuilder;
|
||||
import org.quartz.CronTrigger;
|
||||
import org.quartz.JobBuilder;
|
||||
import org.quartz.JobDataMap;
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.quartz.TriggerBuilder;
|
||||
import org.quartz.TriggerKey;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import com.ruoyi.common.constant.ScheduleConstants;
|
||||
import com.ruoyi.common.exception.job.TaskException;
|
||||
import com.ruoyi.common.exception.job.TaskException.Code;
|
||||
import com.ruoyi.quartz.domain.SysJob;
|
||||
|
||||
/**
|
||||
* 定时任务工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*
|
||||
*/
|
||||
public class ScheduleUtils
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(ScheduleUtils.class);
|
||||
|
||||
/**
|
||||
* 获取触发器key
|
||||
*/
|
||||
public static TriggerKey getTriggerKey(Long jobId)
|
||||
{
|
||||
return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取jobKey
|
||||
*/
|
||||
public static JobKey getJobKey(Long jobId)
|
||||
{
|
||||
return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表达式触发器
|
||||
*/
|
||||
public static CronTrigger getCronTrigger(Scheduler scheduler, Long jobId)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (CronTrigger) scheduler.getTrigger(getTriggerKey(jobId));
|
||||
}
|
||||
catch (SchedulerException e)
|
||||
{
|
||||
log.error("getCronTrigger 异常:", e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建定时任务
|
||||
*/
|
||||
public static void createScheduleJob(Scheduler scheduler, SysJob job)
|
||||
{
|
||||
try
|
||||
{
|
||||
// 构建job信息
|
||||
JobDetail jobDetail = JobBuilder.newJob(ScheduleJob.class).withIdentity(getJobKey(job.getJobId())).build();
|
||||
|
||||
// 表达式调度构建器
|
||||
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
|
||||
cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
|
||||
|
||||
// 按新的cronExpression表达式构建一个新的trigger
|
||||
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(job.getJobId()))
|
||||
.withSchedule(cronScheduleBuilder).build();
|
||||
|
||||
// 放入参数,运行时的方法可以获取
|
||||
jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
|
||||
|
||||
scheduler.scheduleJob(jobDetail, trigger);
|
||||
|
||||
// 暂停任务
|
||||
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
|
||||
{
|
||||
pauseJob(scheduler, job.getJobId());
|
||||
}
|
||||
}
|
||||
catch (SchedulerException e)
|
||||
{
|
||||
log.error("createScheduleJob 异常:", e);
|
||||
}
|
||||
catch (TaskException e)
|
||||
{
|
||||
log.error("createScheduleJob 异常:", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新定时任务
|
||||
*/
|
||||
public static void updateScheduleJob(Scheduler scheduler, SysJob job)
|
||||
{
|
||||
try
|
||||
{
|
||||
TriggerKey triggerKey = getTriggerKey(job.getJobId());
|
||||
|
||||
// 表达式调度构建器
|
||||
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
|
||||
cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
|
||||
|
||||
CronTrigger trigger = getCronTrigger(scheduler, job.getJobId());
|
||||
|
||||
// 按新的cronExpression表达式重新构建trigger
|
||||
trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(cronScheduleBuilder).build();
|
||||
|
||||
// 参数
|
||||
trigger.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
|
||||
|
||||
scheduler.rescheduleJob(triggerKey, trigger);
|
||||
|
||||
// 暂停任务
|
||||
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
|
||||
{
|
||||
pauseJob(scheduler, job.getJobId());
|
||||
}
|
||||
|
||||
}
|
||||
catch (SchedulerException e)
|
||||
{
|
||||
log.error("SchedulerException 异常:", e);
|
||||
}
|
||||
catch (TaskException e)
|
||||
{
|
||||
log.error("SchedulerException 异常:", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 立即执行任务
|
||||
*/
|
||||
public static int run(Scheduler scheduler, SysJob job)
|
||||
{
|
||||
int rows = 0;
|
||||
try
|
||||
{
|
||||
// 参数
|
||||
JobDataMap dataMap = new JobDataMap();
|
||||
dataMap.put(ScheduleConstants.TASK_PROPERTIES, job);
|
||||
|
||||
scheduler.triggerJob(getJobKey(job.getJobId()), dataMap);
|
||||
rows = 1;
|
||||
}
|
||||
catch (SchedulerException e)
|
||||
{
|
||||
log.error("run 异常:", e);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停任务
|
||||
*/
|
||||
public static void pauseJob(Scheduler scheduler, Long jobId)
|
||||
{
|
||||
try
|
||||
{
|
||||
scheduler.pauseJob(getJobKey(jobId));
|
||||
}
|
||||
catch (SchedulerException e)
|
||||
{
|
||||
log.error("pauseJob 异常:", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复任务
|
||||
*/
|
||||
public static void resumeJob(Scheduler scheduler, Long jobId)
|
||||
{
|
||||
try
|
||||
{
|
||||
scheduler.resumeJob(getJobKey(jobId));
|
||||
}
|
||||
catch (SchedulerException e)
|
||||
{
|
||||
log.error("resumeJob 异常:", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除定时任务
|
||||
*/
|
||||
public static void deleteScheduleJob(Scheduler scheduler, Long jobId)
|
||||
{
|
||||
try
|
||||
{
|
||||
scheduler.deleteJob(getJobKey(jobId));
|
||||
}
|
||||
catch (SchedulerException e)
|
||||
{
|
||||
log.error("deleteScheduleJob 异常:", e);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package com.ruoyi.quartz.util;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* spring管理环境中获取bean
|
||||
*
|
||||
* @author yangzz
|
||||
*/
|
||||
@Service("springContextUtil")
|
||||
public class SpringContextUtil implements ApplicationContextAware
|
||||
{
|
||||
// Spring应用上下文环境
|
||||
private static ApplicationContext applicationContext;
|
||||
|
||||
/**
|
||||
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
|
||||
*
|
||||
* @param applicationContext
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
{
|
||||
SpringContextUtil.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ApplicationContext
|
||||
*/
|
||||
public static ApplicationContext getApplicationContext()
|
||||
{
|
||||
return applicationContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象
|
||||
*
|
||||
* @param name
|
||||
* @return Object
|
||||
* @throws BeansException
|
||||
*/
|
||||
public static Object getBean(String name) throws BeansException
|
||||
{
|
||||
return applicationContext.getBean(name);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user