SpringBoot中怎么动态控制定时任务
创始人
2024-12-21 10:02:28
0次

1.定时任务的配置类:SchedulingConfig

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.TaskScheduler;import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;/** * @program: simple-demo * @description: 定时任务配置类 * @author: CaoTing * @date: 2019/5/23 **/@Configurationpublic class SchedulingConfig {  @Bean  public TaskScheduler taskScheduler() {    ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();    // 定时任务执行线程池核心线程数    taskScheduler.setPoolSize(4);    taskScheduler.setRemoveOnCancelPolicy(true);    taskScheduler.setThreadNamePrefix("TaskSchedulerThreadPool-");    return taskScheduler;  }}

2.定时任务注册类:CronTaskRegistrar

这个类包含了新增定时任务,移除定时任务等等核心功能方法

import com.caotinging.demo.task.ScheduledTask;import org.springframework.beans.factory.DisposableBean;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.TaskScheduler;import org.springframework.scheduling.config.CronTask;import org.springframework.stereotype.Component;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;/** * @program: simple-demo * @description: 添加定时任务注册类,用来增加、删除定时任务。 * @author: CaoTing * @date: 2019/5/23 **/@Componentpublic class CronTaskRegistrar implements DisposableBean {  private final Map scheduledTasks = new ConcurrentHashMap<>(16);  @Autowired  private TaskScheduler taskScheduler;  public TaskScheduler getScheduler() {    return this.taskScheduler;  }  /**   * 新增定时任务   * @param task   * @param cronExpression   */  public void addCronTask(Runnable task, String cronExpression) {    addCronTask(new CronTask(task, cronExpression));  }  public void addCronTask(CronTask cronTask) {    if (cronTask != null) {      Runnable task = cronTask.getRunnable();      if (this.scheduledTasks.containsKey(task)) {        removeCronTask(task);      }      this.scheduledTasks.put(task, scheduleCronTask(cronTask));    }  }  /**   * 移除定时任务   * @param task   */  public void removeCronTask(Runnable task) {    ScheduledTask scheduledTask = this.scheduledTasks.remove(task);    if (scheduledTask != null)      scheduledTask.cancel();  }  public ScheduledTask scheduleCronTask(CronTask cronTask) {    ScheduledTask scheduledTask = new ScheduledTask();    scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());    return scheduledTask;  }  @Override  public void destroy() {    for (ScheduledTask task : this.scheduledTasks.values()) {      task.cancel();    }    this.scheduledTasks.clear();  }}

3.定时任务执行类:SchedulingRunnable

import com.caotinging.demo.utils.SpringContextUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.util.ReflectionUtils;import java.lang.reflect.Method;import java.util.Objects;/** * @program: simple-demo * @description: 定时任务运行类 * @author: CaoTing * @date: 2019/5/23 **/public class SchedulingRunnable implements Runnable {  private static final Logger logger = LoggerFactory.getLogger(SchedulingRunnable.class);  private String beanName;  private String methodName;  private Object[] params;  public SchedulingRunnable(String beanName, String methodName) {    this(beanName, methodName, null);  }  public SchedulingRunnable(String beanName, String methodName, Object...params ) {    this.beanName = beanName;    this.methodName = methodName;    this.params = params;  }  @Override  public void run() {    logger.info("定时任务开始执行 - bean:{},方法:{},参数:{}", beanName, methodName, params);    long startTime = System.currentTimeMillis();    try {      Object target = SpringContextUtils.getBean(beanName);      Method method = null;      if (null != params && params.length > 0) {        Class[] paramCls = new Class[params.length];        for (int i = 0; i < params.length; i++) {          paramCls[i] = params[i].getClass();        }        method = target.getClass().getDeclaredMethod(methodName, paramCls);      } else {        method = target.getClass().getDeclaredMethod(methodName);      }      ReflectionUtils.makeAccessible(method);      if (null != params && params.length > 0) {        method.invoke(target, params);      } else {        method.invoke(target);      }    } catch (Exception ex) {      logger.error(String.format("定时任务执行异常 - bean:%s,方法:%s,参数:%s ", beanName, methodName, params), ex);    }    long times = System.currentTimeMillis() - startTime;    logger.info("定时任务执行结束 - bean:{},方法:{},参数:{},耗时:{} 毫秒", beanName, methodName, params, times);  }  @Override  public boolean equals(Object o) {    if (this == o) return true;    if (o == null || getClass() != o.getClass()) return false;    SchedulingRunnable that = (SchedulingRunnable) o;    if (params == null) {      return beanName.equals(that.beanName) &&          methodName.equals(that.methodName) &&          that.params == null;    }    return beanName.equals(that.beanName) &&        methodName.equals(that.methodName) &&        params.equals(that.params);  }  @Override  public int hashCode() {    if (params == null) {      return Objects.hash(beanName, methodName);    }    return Objects.hash(beanName, methodName, params);  }}

4.定时任务控制类:ScheduledTask

import java.util.concurrent.ScheduledFuture;/** * @program: simple-demo * @description: 定时任务控制类 * @author: CaoTing * @date: 2019/5/23 **/public final class ScheduledTask {  public volatile ScheduledFuture future;  /**   * 取消定时任务   */  public void cancel() {    ScheduledFuture future = this.future;    if (future != null) {      future.cancel(true);    }  }}

5.定时任务的测试

编写一个需要用于测试的任务类

import org.springframework.stereotype.Component;/** * @program: simple-demo * @description: * @author: CaoTing * @date: 2019/5/23 **/@Component("demoTask")public class DemoTask {  public void taskWithParams(String param1, Integer param2) {    System.out.println("这是有参示例任务:" + param1 + param2);  }  public void taskNoParams() {    System.out.println("这是无参示例任务");  }}

进行单元测试

import com.caotinging.demo.application.DynamicTaskApplication;import com.caotinging.demo.application.SchedulingRunnable;import com.caotinging.demo.config.CronTaskRegistrar;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * @program: simple-demo * @description: 测试定时任务 * @author: CaoTing * @date: 2019/5/23 **/@RunWith(SpringJUnit4ClassRunner.class)@SpringBootTest(classes = DynamicTaskApplication.class)public class TaskTest {  @Autowired  CronTaskRegistrar cronTaskRegistrar;  @Test  public void testTask() throws InterruptedException {    SchedulingRunnable task = new SchedulingRunnable("demoTask", "taskNoParams", null);    cronTaskRegistrar.addCronTask(task, "0/10 * * * * ?");    // 便于观察    Thread.sleep(3000000);  }  @Test  public void testHaveParamsTask() throws InterruptedException {    SchedulingRunnable task = new SchedulingRunnable("demoTask", "taskWithParams", "haha", 23);    cronTaskRegistrar.addCronTask(task, "0/10 * * * * ?");    // 便于观察    Thread.sleep(3000000);  }}

6.工具类:SpringContextUtils

import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.stereotype.Component;/** * @program: simple-demo * @description: spring获取bean工具类 * @author: CaoTing * @date: 2019/5/23 **/@Componentpublic class SpringContextUtils implements ApplicationContextAware {  private static ApplicationContext applicationContext = null;  @Override  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {    if (SpringContextUtils.applicationContext == null) {      SpringContextUtils.applicationContext = applicationContext;    }  }  //获取applicationContext  public static ApplicationContext getApplicationContext() {    return applicationContext;  }  //通过name获取 Bean.  public static Object getBean(String name) {    return getApplicationContext().getBean(name);  }  //通过class获取Bean.  public static T getBean(Class clazz) {    return getApplicationContext().getBean(clazz);  }  //通过name,以及Clazz返回指定的Bean  public static T getBean(String name, Class clazz) {    return getApplicationContext().getBean(name, clazz);  }}

7.我的pom依赖

         org.springframework.boot      spring-boot-starter-jdbc              com.baomidou      mybatisplus-spring-boot-starter      1.0.5              com.baomidou      mybatis-plus      2.1.9              mysql      mysql-connector-java      runtime              com.alibaba      druid-spring-boot-starter      1.1.9              org.springframework.boot      spring-boot-starter-aop              org.springframework.boot      spring-boot-starter-web                                  org.springframework.boot      spring-boot-starter-test      provided                  org.springframework.boot      spring-boot-starter-data-redis              redis.clients      jedis      2.7.3                  org.apache.httpcomponents      httpclient              org.apache.httpcomponents      httpclient-cache                  org.projectlombok      lombok      true              com.alibaba      fastjson      1.2.31              org.apache.commons      commons-lang3              commons-lang      commons-lang      2.6                  com.google.guava      guava      10.0.1                  com.belerweb      pinyin4j      2.5.0      

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...