定时任务支持Class类调用&多类型参数

This commit is contained in:
RuoYi
2019-07-12 09:37:19 +08:00
parent e7a0f97315
commit d21284f325
20 changed files with 1002 additions and 878 deletions

View File

@@ -76,8 +76,7 @@ public abstract class AbstractQuartzJob implements Job
final SysJobLog sysJobLog = new SysJobLog();
sysJobLog.setJobName(sysJob.getJobName());
sysJobLog.setJobGroup(sysJob.getJobGroup());
sysJobLog.setMethodName(sysJob.getMethodName());
sysJobLog.setMethodParams(sysJob.getMethodParams());
sysJobLog.setInvokeTarget(sysJob.getInvokeTarget());
sysJobLog.setStartTime(startTime);
sysJobLog.setEndTime(new Date());
long runMs = sysJobLog.getEndTime().getTime() - sysJobLog.getStartTime().getTime();

View File

@@ -2,6 +2,8 @@ package com.ruoyi.quartz.util;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.quartz.domain.SysJob;
@@ -20,11 +22,21 @@ public class JobInvokeUtil
*/
public static void invokeMethod(SysJob sysJob) throws Exception
{
Object bean = SpringUtils.getBean(sysJob.getJobName());
String methodName = sysJob.getMethodName();
String methodParams = sysJob.getMethodParams();
String invokeTarget = sysJob.getInvokeTarget();
String beanName = getBeanName(invokeTarget);
String methodName = getMethodName(invokeTarget);
List<Object[]> methodParams = getMethodParams(invokeTarget);
invokeSpringBean(bean, methodName, methodParams);
if (!isValidClassName(beanName))
{
Object bean = SpringUtils.getBean(beanName);
invokeMethod(bean, methodName, methodParams);
}
else
{
Object bean = Class.forName(beanName).newInstance();
invokeMethod(bean, methodName, methodParams);
}
}
/**
@@ -34,14 +46,14 @@ public class JobInvokeUtil
* @param methodName 方法名称
* @param methodParams 方法参数
*/
private static void invokeSpringBean(Object bean, String methodName, String methodParams)
private static void invokeMethod(Object bean, String methodName, List<Object[]> methodParams)
throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException
{
if (StringUtils.isNotEmpty(methodParams))
if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0)
{
Method method = bean.getClass().getDeclaredMethod(methodName, String.class);
method.invoke(bean, methodParams);
Method method = bean.getClass().getDeclaredMethod(methodName, getMethodParamsType(methodParams));
method.invoke(bean, getMethodParamsValue(methodParams));
}
else
{
@@ -49,4 +61,122 @@ public class JobInvokeUtil
method.invoke(bean);
}
}
/**
* 校验是否为为class包名
*
* @param str 名称
* @return true是 false否
*/
public static boolean isValidClassName(String invokeTarget)
{
return StringUtils.countMatches(invokeTarget, ".") > 1;
}
/**
* 获取bean名称
*
* @param invokeTarget 目标字符串
* @return bean名称
*/
public static String getBeanName(String invokeTarget)
{
String beanName = StringUtils.substringBefore(invokeTarget, "(");
return StringUtils.substringBeforeLast(beanName, ".");
}
/**
* 获取bean方法
*
* @param invokeTarget 目标字符串
* @return method方法
*/
public static String getMethodName(String invokeTarget)
{
String methodName = StringUtils.substringBefore(invokeTarget, "(");
return StringUtils.substringAfterLast(methodName, ".");
}
/**
* 获取method方法参数相关列表
*
* @param invokeTarget 目标字符串
* @return method方法相关参数列表
*/
public static List<Object[]> getMethodParams(String invokeTarget)
{
String methodStr = StringUtils.substringBetween(invokeTarget, "(", ")");
if (StringUtils.isEmpty(methodStr))
{
return null;
}
String[] methodParams = methodStr.split(",");
List<Object[]> classs = new LinkedList<>();
for (int i = 0; i < methodParams.length; i++)
{
String str = StringUtils.trimToEmpty(methodParams[i]);
// String字符串类型包含'
if (StringUtils.contains(str, "'"))
{
classs.add(new Object[] { StringUtils.replace(str, "'", ""), String.class });
}
// boolean布尔类型等于true或者false
else if (StringUtils.equals(str, "true") || StringUtils.equalsIgnoreCase(str, "false"))
{
classs.add(new Object[] { Boolean.valueOf(str), Boolean.class });
}
// long长整形包含L
else if (StringUtils.containsIgnoreCase(str, "L"))
{
classs.add(new Object[] { Long.valueOf(StringUtils.replaceIgnoreCase(str, "L", "")), Long.class });
}
// double浮点类型包含D
else if (StringUtils.containsIgnoreCase(str, "D"))
{
classs.add(new Object[] { Double.valueOf(StringUtils.replaceIgnoreCase(str, "D", "")), Double.class });
}
// 其他类型归类为整形
else
{
classs.add(new Object[] { Integer.valueOf(str), Integer.class });
}
}
return classs;
}
/**
* 获取参数类型
*
* @param methodParams 参数相关列表
* @return 参数类型列表
*/
public static Class<?>[] getMethodParamsType(List<Object[]> methodParams)
{
Class<?>[] classs = new Class<?>[methodParams.size()];
int index = 0;
for (Object[] os : methodParams)
{
classs[index] = (Class<?>) os[1];
index++;
}
return classs;
}
/**
* 获取参数值
*
* @param methodParams 参数相关列表
* @return 参数值列表
*/
public static Object[] getMethodParamsValue(List<Object[]> methodParams)
{
Object[] classs = new Object[methodParams.size()];
int index = 0;
for (Object[] os : methodParams)
{
classs[index] = (Object) os[0];
index++;
}
return classs;
}
}

View File

@@ -4,15 +4,12 @@ import org.quartz.CronScheduleBuilder;
import org.quartz.CronTrigger;
import org.quartz.Job;
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;
@@ -26,8 +23,6 @@ import com.ruoyi.quartz.domain.SysJob;
*/
public class ScheduleUtils
{
private static final Logger log = LoggerFactory.getLogger(ScheduleUtils.class);
/**
* 得到quartz任务类
*
@@ -41,35 +36,19 @@ public class ScheduleUtils
}
/**
* 获取触发器key
* 构建任务触发对象
*/
public static TriggerKey getTriggerKey(Long jobId)
public static TriggerKey getTriggerKey(Long jobId, String jobGroup)
{
return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId);
return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
* 获取jobKey
* 构建任务键对象
*/
public static JobKey getJobKey(Long jobId)
public static JobKey getJobKey(Long jobId, String jobGroup)
{
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;
return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
@@ -79,24 +58,26 @@ public class ScheduleUtils
{
Class<? extends Job> jobClass = getQuartzJobClass(job);
// 构建job信息
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(job.getJobId())).build();
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(job.getJobId()))
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup))
.withSchedule(cronScheduleBuilder).build();
// 放入参数,运行时的方法可以获取
jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
// 判断是否存在
if (scheduler.checkExists(getJobKey(job.getJobId())))
if (scheduler.checkExists(getJobKey(jobId, jobGroup)))
{
// 防止创建时存在数据问题 先移除,然后在执行创建操作
scheduler.deleteJob(getJobKey(job.getJobId()));
scheduler.deleteJob(getJobKey(jobId, jobGroup));
}
scheduler.scheduleJob(jobDetail, trigger);
@@ -104,54 +85,13 @@ public class ScheduleUtils
// 暂停任务
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue()))
{
pauseJob(scheduler, job.getJobId());
scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
}
/**
* 更新定时任务
* 设置定时任务策略
*/
public static void updateScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException
{
createScheduleJob(scheduler, job);
}
/**
* 立即执行任务
*/
public static void run(Scheduler scheduler, SysJob job) throws SchedulerException
{
// 参数
JobDataMap dataMap = new JobDataMap();
dataMap.put(ScheduleConstants.TASK_PROPERTIES, job);
scheduler.triggerJob(getJobKey(job.getJobId()), dataMap);
}
/**
* 暂停任务
*/
public static void pauseJob(Scheduler scheduler, Long jobId) throws SchedulerException
{
scheduler.pauseJob(getJobKey(jobId));
}
/**
* 恢复任务
*/
public static void resumeJob(Scheduler scheduler, Long jobId) throws SchedulerException
{
scheduler.resumeJob(getJobKey(jobId));
}
/**
* 删除定时任务
*/
public static void deleteScheduleJob(Scheduler scheduler, Long jobId) throws SchedulerException
{
scheduler.deleteJob(getJobKey(jobId));
}
public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb)
throws TaskException
{
@@ -170,4 +110,4 @@ public class ScheduleUtils
+ "' cannot be used in cron schedule tasks", Code.CONFIG_ERROR);
}
}
}
}