成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

SpringBoot實(shí)現(xiàn)動(dòng)態(tài)控制定時(shí)任務(wù)-支持多參數(shù)

cjie / 2133人閱讀

摘要:由于工作上的原因,需要進(jìn)行定時(shí)任務(wù)的動(dòng)態(tài)增刪改查,網(wǎng)上大部分資料都是整合框架實(shí)現(xiàn)的。本人查閱了一些資料,發(fā)現(xiàn)本身就支持實(shí)現(xiàn)定時(shí)任務(wù)的動(dòng)態(tài)控制。

由于工作上的原因,需要進(jìn)行定時(shí)任務(wù)的動(dòng)態(tài)增刪改查,網(wǎng)上大部分資料都是整合quertz框架實(shí)現(xiàn)的。本人查閱了一些資料,發(fā)現(xiàn)springBoot本身就支持實(shí)現(xiàn)定時(shí)任務(wù)的動(dòng)態(tài)控制。并進(jìn)行改進(jìn),現(xiàn)支持任意多參數(shù)定時(shí)任務(wù)配置

實(shí)現(xiàn)結(jié)果如下圖所示:


后臺(tái)測(cè)試顯示如下:

github 簡(jiǎn)單demo地址如下:
springboot-dynamic-task

1.定時(shí)任務(wù)的配置類: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: 定時(shí)任務(wù)配置類
 * @author: CaoTing
 * @date: 2019/5/23
 **/
@Configuration
public class SchedulingConfig {
    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        // 定時(shí)任務(wù)執(zhí)行線程池核心線程數(shù)
        taskScheduler.setPoolSize(4);
        taskScheduler.setRemoveOnCancelPolicy(true);
        taskScheduler.setThreadNamePrefix("TaskSchedulerThreadPool-");
        return taskScheduler;
    }
}
2.定時(shí)任務(wù)注冊(cè)類:CronTaskRegistrar
這個(gè)類包含了新增定時(shí)任務(wù),移除定時(shí)任務(wù)等等核心功能方法
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: 添加定時(shí)任務(wù)注冊(cè)類,用來(lái)增加、刪除定時(shí)任務(wù)。
 * @author: CaoTing
 * @date: 2019/5/23
 **/
@Component
public class CronTaskRegistrar implements DisposableBean {

    private final Map scheduledTasks = new ConcurrentHashMap<>(16);

    @Autowired
    private TaskScheduler taskScheduler;

    public TaskScheduler getScheduler() {
        return this.taskScheduler;
    }

    /**
     * 新增定時(shí)任務(wù)
     * @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));
        }
    }

    /**
     * 移除定時(shí)任務(wù)
     * @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.定時(shí)任務(wù)執(zhí)行類: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: 定時(shí)任務(wù)運(yùn)行類
 * @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("定時(shí)任務(wù)開(kāi)始執(zhí)行 - bean:{},方法:{},參數(shù):{}", 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("定時(shí)任務(wù)執(zhí)行異常 - bean:%s,方法:%s,參數(shù):%s ", beanName, methodName, params), ex);
        }

        long times = System.currentTimeMillis() - startTime;
        logger.info("定時(shí)任務(wù)執(zhí)行結(jié)束 - bean:{},方法:{},參數(shù):{},耗時(shí):{} 毫秒", 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.定時(shí)任務(wù)控制類:ScheduledTask
import java.util.concurrent.ScheduledFuture;

/**
 * @program: simple-demo
 * @description: 定時(shí)任務(wù)控制類
 * @author: CaoTing
 * @date: 2019/5/23
 **/
public final class ScheduledTask {

    public volatile ScheduledFuture future;
    /**
     * 取消定時(shí)任務(wù)
     */
    public void cancel() {
        ScheduledFuture future = this.future;
        if (future != null) {
            future.cancel(true);
        }
    }
}
5.定時(shí)任務(wù)的測(cè)試
編寫(xiě)一個(gè)需要用于測(cè)試的任務(wù)類
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("這是有參示例任務(wù):" + param1 + param2);
    }

    public void taskNoParams() {
        System.out.println("這是無(wú)參示例任務(wù)");
    }
}
進(jìn)行單元測(cè)試
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: 測(cè)試定時(shí)任務(wù)
 * @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
 **/
@Component
public 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;
    }

    //通過(guò)name獲取 Bean.
    public static Object getBean(String name) {
        return getApplicationContext().getBean(name);
    }

    //通過(guò)class獲取Bean.
    public static  T getBean(Class clazz) {
        return getApplicationContext().getBean(clazz);
    }

    //通過(guò)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
        
    
8.總結(jié)

建議移步github獲取簡(jiǎn)單demo上手實(shí)踐哦,在本文文首哦。有幫助的話點(diǎn)個(gè)贊吧,筆芯。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/74724.html

相關(guān)文章

  • SpringBoot中并發(fā)定時(shí)任務(wù)實(shí)現(xiàn)、動(dòng)態(tài)定時(shí)任務(wù)實(shí)現(xiàn)(看這一篇就夠了)

    摘要:也是自帶的一個(gè)基于線程池設(shè)計(jì)的定時(shí)任務(wù)類。其每個(gè)調(diào)度任務(wù)都會(huì)分配到線程池中的一個(gè)線程執(zhí)行,所以其任務(wù)是并發(fā)執(zhí)行的,互不影響。 原創(chuàng)不易,如需轉(zhuǎn)載,請(qǐng)注明出處https://www.cnblogs.com/baixianlong/p/10659045.html,否則將追究法律責(zé)任?。。?一、在JAVA開(kāi)發(fā)領(lǐng)域,目前可以通過(guò)以下幾種方式進(jìn)行定時(shí)任務(wù) 1、單機(jī)部署模式 Timer:jdk中...

    BWrong 評(píng)論0 收藏0
  • Springboot整合Quartz實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)

    摘要:本文使用實(shí)現(xiàn)對(duì)定時(shí)任務(wù)的增刪改查啟用停用等功能。并把定時(shí)任務(wù)持久化到數(shù)據(jù)庫(kù)以及支持集群。決定什么時(shí)候來(lái)執(zhí)行任務(wù)。定義的是任務(wù)數(shù)據(jù),而真正的執(zhí)行邏輯是在中。封裝定時(shí)任務(wù)接口添加一個(gè)暫?;謴?fù)刪除修改暫停所有恢復(fù)所有 簡(jiǎn)介 Quartz是一款功能強(qiáng)大的任務(wù)調(diào)度器,可以實(shí)現(xiàn)較為復(fù)雜的調(diào)度功能,如每月一號(hào)執(zhí)行、每天凌晨執(zhí)行、每周五執(zhí)行等等,還支持分布式調(diào)度。本文使用Springboot+Myba...

    IamDLY 評(píng)論0 收藏0
  • springboot整合quarzt實(shí)現(xiàn)動(dòng)態(tài)定時(shí)任務(wù)

    摘要:而我這里定時(shí)任務(wù)的觸發(fā)是要通過(guò)接口的方式來(lái)觸發(fā),所以只用實(shí)現(xiàn)以下的調(diào)度器即可。我這里簡(jiǎn)單說(shuō)下任務(wù)的調(diào)度器,具體的任務(wù)類,觸發(fā)器,任務(wù)什么時(shí)候執(zhí)行是由它決定的。遇到的坑解決方式這個(gè)是因?yàn)椴患嫒莸膯?wèn)題,所以使用是不會(huì)出現(xiàn)這個(gè)錯(cuò)誤的。 實(shí)現(xiàn)定時(shí)任務(wù)的幾種方式: 1.使用linux的crontab 優(yōu)點(diǎn): 1.使用方式很簡(jiǎn)單,只要在crontab中寫(xiě)好 2.隨時(shí)可以修改,不需要...

    hoohack 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<