SPRING BOOT 动态定时任务

0.前言

传统spring定时任务采用的是@Sechedu注解去实现,但是该注解只能指定固定的时间任务,例如:配置了2s执行一次,那么永远只能是每两秒执行一次

但是在有些特殊场景下需要一些动态定时任务,例如:最初配置了2s执行一次,在执行任务中,修改配置为5秒执行一次,那么就需要动态的加载配置,使任务动态的变成5s执行一次

1.原理

要想实现动态定时任务,就需要借助SpringSchedulingConfigurer接口,该方式可以实现动态时间,定时任务,具体原理如下图:

2.Cron设计

如下图所示

定时任务数据库表设计

3. 配置解释

3.1 SchedulingConfigurer

要想实现定时任务主要是实现SchedulingConfigurer接口,然后重写configureTasks方法

3.2 ScheduledTaskRegistrar

configureTasks方法中,ScheduledTaskRegistrar通过addTriggerTask来添加触发器任务,从而去执行。而addTriggerTask方法有两个参数,一个是要执行得任务,一个是触发器

 具体配置代码如下:

package net.test.api.job;import io.lettuce.core.dynamic.support.ReflectionUtils;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import net.test.demo.common.framework.SpringContext;
import net.test.dao.entity.demo.ScheduleSetting;
import net.test.dao.mapper.demo.ScheduledSettingMapper;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;@Component
public class CronSchedule implements SchedulingConfigurer {@Autowiredprivate ScheduledSettingMapper scheduledSettingMapper;@Overridepublic void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {// 获取所有任务List scheduleList = scheduledSettingMapper.getScheduleList();System.out.println(scheduleList.size());if (CollectionUtils.isNotEmpty(scheduleList)){for (ScheduleSetting s : scheduleList){scheduledTaskRegistrar.addTriggerTask(getRunnable(s), getTrigger(s));}}}/*** 转换首字母小写** @param str* @return*/public static String lowerFirstCapse(String str) {char[] chars = str.toCharArray();chars[0] += 32;return String.valueOf(chars);}private Runnable getRunnable(ScheduleSetting scheduleSetting){return new Runnable() {@Overridepublic void run() {Class clazz;try {clazz = Class.forName(scheduleSetting.getBeanName());String className = lowerFirstCapse(clazz.getSimpleName());Object bean = SpringContext.getBean(className);Method method = ReflectionUtils.findMethod(bean.getClass(), scheduleSetting.getMethodName());if (StringUtils.isNotEmpty(scheduleSetting.getMethodParams())) {ReflectionUtils.invokeMethod(method, bean, scheduleSetting.getMethodParams());} else {ReflectionUtils.invokeMethod(method, bean);}} catch (ClassNotFoundException e) {e.printStackTrace();}}};}private Trigger getTrigger(ScheduleSetting scheduleSetting){return new Trigger() {@Overridepublic Date nextExecutionTime(TriggerContext triggerContext) {CronTrigger trigger = new CronTrigger(scheduleSetting.getCronExpression());Date nextExec = trigger.nextExecutionTime(triggerContext);return nextExec;}};}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部