欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

springboot使用TaskScheduler實(shí)現(xiàn)動(dòng)態(tài)增刪啟停定時(shí)任務(wù)方式

 更新時(shí)間:2024年08月21日 14:44:25   作者:?abc!  
這篇文章主要介紹了springboot使用TaskScheduler實(shí)現(xiàn)動(dòng)態(tài)增刪啟停定時(shí)任務(wù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

TaskScheduler

概述

TaskScheduler是spring 3.0版本后,自帶了一個(gè)定時(shí)任務(wù)工具,不用配置文件,可以動(dòng)態(tài)改變執(zhí)行狀態(tài)。也可以使用cron表達(dá)式設(shè)置定時(shí)任務(wù)。

被執(zhí)行的類要實(shí)現(xiàn)Runnable接口

TaskScheduler是一個(gè)接口,它定義了6個(gè)方法

接口的6種方法

public interface TaskScheduler { 

/** 
* 提交任務(wù)調(diào)度請(qǐng)求 
* @param task 待執(zhí)行任務(wù)   
* @param trigger 使用Trigger指定任務(wù)調(diào)度規(guī)則 
* @return 
*/
ScheduledFuture schedule(Runnable task, Trigger trigger);

/** 
* 提交任務(wù)調(diào)度請(qǐng)求 
* 注意任務(wù)只執(zhí)行一次,使用startTime指定其啟動(dòng)時(shí)間  
* @param task 待執(zhí)行任務(wù) 
* @param startTime 任務(wù)啟動(dòng)時(shí)間 
* @return 
*/
ScheduledFuture schedule(Runnable task, Date startTime);


/** 
* 使用fixedRate的方式提交任務(wù)調(diào)度請(qǐng)求 
* 任務(wù)首次啟動(dòng)時(shí)間由傳入?yún)?shù)指定 
* @param task 待執(zhí)行的任務(wù)  
* @param startTime 任務(wù)啟動(dòng)時(shí)間 
* @param period 兩次任務(wù)啟動(dòng)時(shí)間之間的間隔時(shí)間,默認(rèn)單位是毫秒 
* @return 
*/
ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period);

/** 
* 使用fixedRate的方式提交任務(wù)調(diào)度請(qǐng)求 
* 任務(wù)首次啟動(dòng)時(shí)間未設(shè)置,任務(wù)池將會(huì)盡可能早的啟動(dòng)任務(wù) 
* @param task 待執(zhí)行任務(wù) 
* @param period 兩次任務(wù)啟動(dòng)時(shí)間之間的間隔時(shí)間,默認(rèn)單位是毫秒 
* @return 
*/
ScheduledFuture scheduleAtFixedRate(Runnable task, long period);

/** 
* 使用fixedDelay的方式提交任務(wù)調(diào)度請(qǐng)求 
* 任務(wù)首次啟動(dòng)時(shí)間由傳入?yún)?shù)指定 
* @param task 待執(zhí)行任務(wù) 
* @param startTime 任務(wù)啟動(dòng)時(shí)間 
* @param delay 上一次任務(wù)結(jié)束時(shí)間與下一次任務(wù)開始時(shí)間的間隔時(shí)間,單位默認(rèn)是毫秒 
* @return 
*/
ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay);

/** 
* 使用fixedDelay的方式提交任務(wù)調(diào)度請(qǐng)求 
* 任務(wù)首次啟動(dòng)時(shí)間未設(shè)置,任務(wù)池將會(huì)盡可能早的啟動(dòng)任務(wù) 
* @param task 待執(zhí)行任務(wù) 
* @param delay 上一次任務(wù)結(jié)束時(shí)間與下一次任務(wù)開始時(shí)間的間隔時(shí)間,單位默認(rèn)是毫秒 
* @return 
*/
ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay);
}

0、ThreadPoolTaskScheduler

在 ThreadPoolTaskSchedulerConfig 中定義 ThreadPoolTaskScheduler bean

@Configuration
public class ThreadPoolTaskSchedulerConfig {

    @Bean
    public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
        ThreadPoolTaskScheduler threadPoolTaskScheduler
          = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(5);
        threadPoolTaskScheduler.setThreadNamePrefix(
          "ThreadPoolTaskScheduler");
        return threadPoolTaskScheduler;
    }
}

配置的 bean threadPoolTaskScheduler 可以根據(jù)配置的池大小 5 異步執(zhí)行任務(wù)。

請(qǐng)注意,所有與 ThreadPoolTaskScheduler 相關(guān)的線程名稱都將以ThreadPoolTaskScheduler 為前綴。

讓我們實(shí)現(xiàn)一個(gè)簡單的任務(wù),然后我們可以安排:

class RunnableTask implements Runnable{
    private String message;
    
    public RunnableTask(String message){
        this.message = message;
    }
    
    @Override
    public void run() {
        System.out.println(new Date()+" Runnable Task with "+message
          +" on thread "+Thread.currentThread().getName());
    }
}

1、schedule(Runnable task, Trigger trigger)

指定一個(gè)觸發(fā)器執(zhí)行定時(shí)任務(wù)??梢允褂肅ronTrigger來指定Cron表達(dá)式,執(zhí)行定時(shí)任務(wù)

如下:使用CronTrigger 來根據(jù) cron 表達(dá)式調(diào)度任務(wù),可以使用提供的觸發(fā)器按照某個(gè)指定的節(jié)奏或時(shí)間表運(yùn)行任務(wù),在這種情況下,RunnableTask 將在每分鐘的第 10 秒執(zhí)行。

taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger);

2、schedule(Runnable task, Date startTime);

指定一個(gè)具體時(shí)間點(diǎn)執(zhí)行定時(shí)任務(wù),可以動(dòng)態(tài)的指定時(shí)間,開啟任務(wù),只執(zhí)行一次

如下:配置一個(gè)任務(wù)在 1000 毫秒的固定延遲后運(yùn)行,RunnableTask 將始終在一次執(zhí)行完成和下一次執(zhí)行開始之間運(yùn)行 1000 毫秒。

taskScheduler.schedule(
  new Runnabletask("Specific time, 3 Seconds from now"),
  new Date(System.currentTimeMillis + 3000)
);

3、scheduleAtFixedRate(Runnable task, long period);

立即執(zhí)行,循環(huán)任務(wù),指定一個(gè)執(zhí)行周期(毫秒計(jì)時(shí))

PS:不管上一個(gè)周期是否執(zhí)行完,到時(shí)間下個(gè)周期就開始執(zhí)行

如下:安排一個(gè)任務(wù)以固定的毫秒速率運(yùn)行,下一個(gè) RunnableTask 將始終在 2000 毫秒后運(yùn)行,而不管上次執(zhí)行的狀態(tài)如何,它可能仍在運(yùn)行。

taskScheduler.scheduleAtFixedRate(
  new RunnableTask("Fixed Rate of 2 seconds") , 
  2000);

4、scheduleAtFixedRate(Runnable task, Date startTime, long period);

指定時(shí)間開始執(zhí)行,循環(huán)任務(wù),指定一個(gè)間隔周期(毫秒計(jì)時(shí))

PS:不管上一個(gè)周期是否執(zhí)行完,到時(shí)間下個(gè)周期就開始執(zhí)行

如下:使用CronTrigger 來根據(jù) cron 表達(dá)式調(diào)度任務(wù),可以使用提供的觸發(fā)器按照某個(gè)指定的節(jié)奏或時(shí)間表運(yùn)行任務(wù),在這種情況下,RunnableTask 將在每分鐘的第 10 秒執(zhí)行。

taskScheduler.scheduleAtFixedRate(new RunnableTask(
  "Fixed Rate of 2 seconds"), new Date(), 3000);

5、scheduleWithFixedDelay(Runnable task, long delay);

立即執(zhí)行,循環(huán)任務(wù),指定一個(gè)間隔周期(毫秒計(jì)時(shí))

PS:上一個(gè)周期執(zhí)行完,等待delay時(shí)間,下個(gè)周期開始執(zhí)行

如下:配置一個(gè)任務(wù)在 1000 毫秒的固定延遲后運(yùn)行,RunnableTask 將始終在一次執(zhí)行完成和下一次執(zhí)行開始之間運(yùn)行 1000 毫秒。

taskScheduler.scheduleWithFixedDelay(
  new RunnableTask("Fixed 1 second Delay"), 
  1000);

6、scheduleWithFixedDelay(Runnable task, Date startTime, long delay);

指定時(shí)間開始執(zhí)行,循環(huán)任務(wù),指定一個(gè)間隔周期(毫秒計(jì)時(shí))

PS:上一個(gè)周期執(zhí)行完,等待delay時(shí)間,下個(gè)周期開始執(zhí)行

如下:將任務(wù)配置為在給定開始時(shí)間的固定延遲后運(yùn)行,RunnableTask 將在指定的執(zhí)行時(shí)間被調(diào)用,其中包括 @PostConstruct 方法開始的時(shí)間,隨后延遲 1000 毫秒。

taskScheduler.scheduleWithFixedDelay(
  new RunnableTask("Current Date Fixed 1 second Delay"),
  new Date(),
  1000);

接口5個(gè)實(shí)現(xiàn)類

1、ConcurrentTaskScheduler

以當(dāng)前線程執(zhí)行任務(wù),如果任務(wù)簡單,可以直接使用這個(gè)類來執(zhí)行,快捷方便

  • 單線程運(yùn)行
public class LocTest implements Runnable {
  private ConcurrentTaskScheduler concurrentTaskScheduler = new ConcurrentTaskScheduler();
  private void start() {
    concurrentTaskScheduler.schedule(this, new Date());
  }
  public void run() {
    Thread thread = Thread.currentThread();
    System.out.println("current id:" + thread.getId());
    System.out.println("current name:" + thread.getName());
  }
  public static void main(String[] args) {
    new LocTest().start();
  }
}

2、DefaultManagedTaskScheduler

以當(dāng)前線程執(zhí)行任務(wù),是ConcurrentTaskScheduler的子類,添加了JNDI的支持。

和ConcurrentTaskScheduler一樣的用法,需要使用JNDI可以單獨(dú)設(shè)置

3、ThreadPoolTaskScheduler

TaskScheduler接口的默認(rèn)實(shí)現(xiàn)類,多線程定時(shí)任務(wù)執(zhí)行??梢栽O(shè)置執(zhí)行線程池?cái)?shù)(默認(rèn)一個(gè)線程)

  • 使用前必須得先調(diào)用initialize()【初始化方法】
  • shutDown()方法,執(zhí)行完后可以關(guān)閉線程

除實(shí)現(xiàn)了TaskScheduler接口中的方法外,它還包含了一些對(duì)ScheduledThreadPoolExecutor進(jìn)行操作的接口,其常用方法如下:

  • setPoolSize:設(shè)置線程池大小,最小為1,默認(rèn)情況下也為1;
  • setErrorHandler :設(shè)置異常處理器。
  • getScheduledThreadPoolExecutor :獲取ScheduledExecutor,默認(rèn)ScheduledThreadPoolExecutor類型。
  • getActiveCount :獲取當(dāng)前活動(dòng)的線程數(shù)
  • execute : 提交執(zhí)行一次的任務(wù)
  • submit\submitListenable :提交執(zhí)行一次的任務(wù),并且返回一個(gè)Future對(duì)象供判斷任務(wù)狀態(tài)使用
public class LocTest implements Runnable {
	private ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
	private void start() {
		taskScheduler.setPoolSize(10);
		//必須得先初始化,才能使用
		taskScheduler.initialize();
		taskScheduler.schedule(this, new Date());
	}
	public void run() {
		Thread ct = Thread.currentThread();
		System.out.println("current id:"+ct.getId());
		System.out.println("current name:"+ct.getName());
	}
	public static void main(String[] args) {
		new LocTest().start();
	}
}

4、TimerManagerTaskScheduler

用于包裝CommonJ中的TimerManager接口。

在使用CommonJ進(jìn)行調(diào)度時(shí)使用

spring boot使用TaskScheduler實(shí)現(xiàn)動(dòng)態(tài)增刪啟停定時(shí)任務(wù)

SchedulingConfig:添加執(zhí)行定時(shí)任務(wù)的線程池配置類

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;

@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;
    }
}

ScheduledTask:添加ScheduledFuture的包裝類

ScheduledFuture是ScheduledExecutorService定時(shí)任務(wù)線程池的執(zhí)行結(jié)果。

import java.util.concurrent.ScheduledFuture;
public final class ScheduledTask {
    volatile ScheduledFuture<?> future;

    /**
     * 取消定時(shí)任務(wù)
     */
    public void cancel() {
        ScheduledFuture<?> future = this.future;
        if (future != null) {
            future.cancel(true);
        }
    }
}

SchedulingRunnable:添加Runnable接口實(shí)現(xiàn)類

添加Runnable接口實(shí)現(xiàn)類,被定時(shí)任務(wù)線程池調(diào)用,用來執(zhí)行指定bean里面的方法

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;

import java.lang.reflect.Method;
import java.util.Objects;


public class SchedulingRunnable implements Runnable {

    private static final Logger logger = LoggerFactory.getLogger(SchedulingRunnable.class);

    private final String beanName;

    private final String methodName;

    private final String params;

    public SchedulingRunnable(String beanName, String methodName) {
        this(beanName, methodName, null);
    }

    public SchedulingRunnable(String beanName, String methodName, String params) {
        this.beanName = beanName;
        this.methodName = methodName;
        this.params = params;
    }



    @Override
    public void run() {
        logger.info("定時(shí)任務(wù)開始執(zhí)行 - bean:{},方法:{},參數(shù):{}", beanName, methodName, params);
        long startTime = System.currentTimeMillis();

        try {
            Object target = SpringContextUtils.getBean(beanName);

            Method method = null;
            if (StringUtils.isNotEmpty(params)) {
                method = target.getClass().getDeclaredMethod(methodName, String.class);
            } else {
                method = target.getClass().getDeclaredMethod(methodName);
            }

            ReflectionUtils.makeAccessible(method);
            if (StringUtils.isNotEmpty(params)) {
                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);
    }
}

CronTaskRegistrar:添加定時(shí)任務(wù)注冊(cè)類,用來增加、刪除定時(shí)任務(wù)

import com.example.testspringboot.cron.ScheduleResult;
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.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 添加定時(shí)任務(wù)注冊(cè)類,用來增加、刪除定時(shí)任務(wù)。
 */
@Component
public class CronTaskRegistrar implements DisposableBean {

    private final Map<Runnable, ScheduledTask> scheduledTasks = new ConcurrentHashMap<>(16);
    private final Map<Integer, ScheduleResult> schedulerJob = new HashMap<>();
    @Autowired
    private TaskScheduler taskScheduler;

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

    public void addCronTask(ScheduleResult scheduleResult) {
        SchedulingRunnable task = new SchedulingRunnable(scheduleResult.getBeanName(), scheduleResult.getMethodName(), scheduleResult.getMethodParams());
        String cronExpression = scheduleResult.getCronExpression();

        CronTask cronTask = new CronTask(task, cronExpression);
        // 如果當(dāng)前包含這個(gè)任務(wù),則移除
        if (this.scheduledTasks.containsKey(task)) {
            removeCronTask(scheduleResult.getBeanName(), scheduleResult.getMethodName(), scheduleResult.getMethodParams());
        }
        schedulerJob.put(scheduleResult.getJobId(), scheduleResult);
        this.scheduledTasks.put(task, scheduleCronTask(cronTask));
    }

    public void removeCronTask(String beanName, String methodName, String methodParams) {
        SchedulingRunnable task = new SchedulingRunnable(beanName, methodName, methodParams);
        ScheduledTask scheduledTask = this.scheduledTasks.remove(task);
        if (scheduledTask != null) {
            scheduledTask.cancel();
        }
    }

    public void removeCronTask(ScheduleResult scheduleResult) {
        schedulerJob.put(scheduleResult.getJobId(), scheduleResult);
        removeCronTask(scheduleResult.getBeanName(), scheduleResult.getMethodName(), scheduleResult.getMethodParams());
    }

    public ScheduledTask scheduleCronTask(CronTask cronTask) {
        ScheduledTask scheduledTask = new ScheduledTask();
        scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
        return scheduledTask;
    }


    public Map<Runnable, ScheduledTask> getScheduledTasks() {
        return scheduledTasks;
    }

    public Map<Integer, ScheduleResult> getSchedulerJob() {
        return schedulerJob;
    }

    @Override
    public void destroy() {
        for (ScheduledTask task : this.scheduledTasks.values()) {
            task.cancel();
        }

        this.scheduledTasks.clear();
    }

    public ScheduleResult getSchedulerByJobId(Integer jobId) {
        for (ScheduleResult job : findAllTask()) {
            if (jobId.equals(job.getJobId())) {
                return job;
            }
        }
        return null;
    }

    public List<ScheduleResult> findAllTask() {
        List<ScheduleResult> ScheduleResults = new ArrayList<>();
        Set<Map.Entry<Integer, ScheduleResult>> entries = schedulerJob.entrySet();
        for (Map.Entry<Integer, ScheduleResult> en : entries) {
            ScheduleResults.add(en.getValue());
        }
        return ScheduleResults;
    }


}

CronUtils:校驗(yàn)Cron表達(dá)式的有效性

import org.springframework.scheduling.support.CronExpression;

public class CronUtils {
    /**
     * 返回一個(gè)布爾值代表一個(gè)給定的Cron表達(dá)式的有效性
     *
     * @param cronExpression Cron表達(dá)式
     * @return boolean 表達(dá)式是否有效
     */
    public static boolean isValid(String cronExpression) {
        return CronExpression.isValidExpression(cronExpression);
    }


}

ScheduleResult:添加定時(shí)任務(wù)實(shí)體類

import lombok.Data;


@Data
public class ScheduleResult {
    /**
     * 任務(wù)ID
     */
    private Integer jobId;
    /**
     * bean名稱
     */
    private String beanName;
    /**
     * 方法名稱
     */
    private String methodName;
    /**
     * 方法參數(shù): 執(zhí)行service里面的哪一種方法
     */
    private String methodParams;
    /**
     * cron表達(dá)式
     */
    private String cronExpression;
    /**
     * 狀態(tài)(1正常 0暫停)
     */
    private Integer jobStatus;
    /**
     * 備注
     */
    private String remark;
    /**
     * 創(chuàng)建時(shí)間
     */
    private String createTime;
    /**
     * 更新時(shí)間
     */
    private String updateTime;

}

ScheduleJobStatus:任務(wù)狀態(tài)枚舉類型

public enum ScheduleJobStatus {
    /**
     * 暫停
     */
    PAUSE,

    /**
     * 正常
     */
    NORMAL;

}

SpringContextUtils類:從spring容器里獲取bean

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@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;
        }
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

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

    }

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

    }

    // 通過name,以及Clazz返回指定的Bean
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }

    public static boolean containsBean(String name) {
        return getApplicationContext().containsBean(name);
    }

    public static boolean isSingleton(String name) {
        return getApplicationContext().isSingleton(name);
    }

    public static Class<? extends Object> getType(String name) {
        return getApplicationContext().getType(name);
    }
}

ScheduleJobService:增刪啟停service方法

@Service
@Slf4j
public class ScheduleJobService {


    @Autowired
    private CronTaskRegistrar cronTaskRegistrar;

    public void addScheduleJob(ScheduleResult scheduleResult) {
        long currentTimeMillis = System.currentTimeMillis();
        scheduleResult.setCreateTime(formatTimeYMD_HMS_SSS(currentTimeMillis));
        scheduleResult.setUpdateTime(formatTimeYMD_HMS_SSS(currentTimeMillis));
        scheduleResult.setJobId(findAllTask().size() + 1);
        if (scheduleResult.getJobStatus().equals(ScheduleJobStatus.NORMAL.ordinal())) {
            log.info("Stop or pause: is now on");
            cronTaskRegistrar.addCronTask(scheduleResult);
            return;
        }
        cronTaskRegistrar.getSchedulerJob().put(scheduleResult.getJobId(), scheduleResult);
    }

    public void editScheduleJob(ScheduleResult currentSchedule) {
        //先移除
        cronTaskRegistrar.removeCronTask(currentSchedule.getBeanName(), currentSchedule.getMethodName(), currentSchedule.getMethodParams());
        ScheduleResult pastScheduleJob = cronTaskRegistrar.getSchedulerByJobId(currentSchedule.getJobId());
        if (pastScheduleJob == null) {
            System.out.println("沒有這個(gè)任務(wù)");
            return;
        }
        //然后判斷是否開啟, 如果開啟的話,現(xiàn)在立即執(zhí)行
        startOrStopSchedulerJob(currentSchedule, true);
    }

    public void deleteScheduleJob(ScheduleResult scheduleResult) {
        // 清除這個(gè)任務(wù)
        cronTaskRegistrar.removeCronTask(scheduleResult.getBeanName(), scheduleResult.getMethodName(), scheduleResult.getMethodParams());
        // 清除這個(gè)任務(wù)的數(shù)據(jù)
        cronTaskRegistrar.getSchedulerJob().remove(scheduleResult.getJobId());
    }

    public void startOrStopScheduler(ScheduleResult scheduleResult) {
        cronTaskRegistrar.getSchedulerJob().get(scheduleResult.getJobId()).setJobStatus(scheduleResult.getJobStatus());
        startOrStopSchedulerJob(scheduleResult, false);
    }

    private void startOrStopSchedulerJob(ScheduleResult scheduleResult, boolean update) {
        // 更新時(shí)間
        scheduleResult.setUpdateTime(formatTimeYMD_HMS_SSS(System.currentTimeMillis()));
        if (scheduleResult.getJobStatus().equals(ScheduleJobStatus.NORMAL.ordinal())) {
            System.out.println("停止或暫停:現(xiàn)在是開啟");
            cronTaskRegistrar.addCronTask(scheduleResult);
            return;
        }
        System.out.println("停止或暫停:現(xiàn)在是暫停");
        if (update){
            cronTaskRegistrar.removeCronTask(scheduleResult);
            return;
        }
        cronTaskRegistrar.removeCronTask(scheduleResult.getBeanName(), scheduleResult.getMethodName(), scheduleResult.getMethodParams());
    }

    public List<ScheduleResult> findAllTask() {
        return cronTaskRegistrar.findAllTask();
    }


    // 轉(zhuǎn)換為年-月-日 時(shí):分:秒
    private String formatTimeYMD_HMS_SSS(long time) {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS").format(time);
    }

}

cronController:訪問接口

import com.example.testspringboot.cron.ScheduleResult;
import com.example.testspringboot.cron.ScheduleJobService;
import com.example.testspringboot.cron.utils.CronUtils;
import com.google.gson.Gson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
public class cronController {
    @Autowired
    private ScheduleJobService scheduleJobService;
    /**
     * 測(cè)試上傳的用例文件, 獲取詳細(xì)執(zhí)行結(jié)果
     */
    @PostMapping("/add")
    void executeTestOneFile(@RequestBody ScheduleResult scheduleResult) {
        boolean valid = CronUtils.isValid(scheduleResult.getCronExpression());
        if (valid){
            System.out.println("校驗(yàn)成功, 添加任務(wù)");
            scheduleResult.setMethodParams(scheduleResult.getBranch()+scheduleResult.getCaseDir());
            scheduleJobService.addScheduleJob(scheduleResult);
        }else {
            System.out.println("校驗(yàn)失敗");
        }
    }

    @PostMapping("/stop")
    void end(@RequestBody ScheduleResult scheduleResult) {
        Gson gson = new Gson();

        System.out.println("================");
        System.out.println(scheduleResult);
        System.out.println("=================");
        scheduleResult.setJobStatus(0);
        scheduleJobService.startOrStopScheduler(scheduleResult);
    }
    @PostMapping("/start")
    void start(@RequestBody ScheduleResult scheduleResult) {
        System.out.println("================");
        System.out.println(scheduleResult);
        System.out.println("=================");
        scheduleResult.setJobStatus(1);
        scheduleJobService.startOrStopScheduler(scheduleResult);
    }

    @PostMapping("/edit")
    void edit(@RequestBody ScheduleResult scheduleResult) {
        System.out.println("=======edit=========");
        System.out.println(scheduleResult);
        System.out.println("=================");
        scheduleJobService.editScheduleJob(scheduleResult);
    }

    @PostMapping("/delete")
    void delete(@RequestBody ScheduleResult scheduleResult) {
        System.out.println("=======delete=========");
        System.out.println(scheduleResult);
        System.out.println("=================");
        scheduleJobService.deleteScheduleJob(scheduleResult);
    }

    @GetMapping("/tasks")
    List<ScheduleResult> get() throws Exception {
        List<ScheduleResult> allTask = scheduleJobService.findAllTask();
        System.out.println("現(xiàn)在的定時(shí)任務(wù)數(shù)量 = " + allTask.size());
        System.out.println("現(xiàn)在的定時(shí)任務(wù) = " + allTask);
        return allTask;
    }


}

c1:測(cè)試bean

import org.springframework.stereotype.Component;

@Component
public class c1 {
    public void test1(String y){
        System.out.println("這個(gè)是test1的bean : " + y);
    }
    public void test2(){
        System.out.println("這個(gè)是test1的bean中test2方法");
    }
}

init:項(xiàng)目啟動(dòng)后的定時(shí)任務(wù)

import com.example.testspringboot.cron.ScheduleJobService;
import com.example.testspringboot.cron.ScheduleResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class init  implements CommandLineRunner {
    @Autowired
    private ScheduleJobService scheduleJobService;

    @Override
    public void run(String... args) throws Exception {
        System.out.println("開始珍惜");
        ScheduleResult scheduleResult = new ScheduleResult();
        scheduleResult.setBeanName("c1");
        scheduleResult.setMethodName("test1");
        scheduleResult.setCronExpression("0/25 * * * * *");
        scheduleResult.setJobStatus(1);
        scheduleResult.setMethodParams("test1");
        scheduleJobService.addScheduleJob(scheduleResult);
        scheduleJobService.findAllTask();
    }
}

后續(xù)的操作,基本上就是復(fù)制粘貼,運(yùn)行

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 深入了解Java核心類庫--Objects類

    深入了解Java核心類庫--Objects類

    這篇文章主要介紹了Java中的Object類詳細(xì)介紹,本文講解了Object類的作用、Object類的主要方法、Object類中不能被重寫的方法、Object類的equals方法重寫實(shí)例等內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • SpringBoot詳細(xì)介紹SPI機(jī)制示例

    SpringBoot詳細(xì)介紹SPI機(jī)制示例

    這篇文章主要介紹了深入解析Spring Boot的SPI機(jī)制詳情,SPI是JDK內(nèi)置的一種服務(wù)提供發(fā)現(xiàn)機(jī)制,可以用來啟用框架擴(kuò)展和替換組件,主要用于框架中開發(fā),更多相關(guān)介紹,感興趣的小伙伴可以參考一下下面文章內(nèi)容
    2022-08-08
  • Java判斷字符串為空、字符串是否為數(shù)字

    Java判斷字符串為空、字符串是否為數(shù)字

    這篇文章主要介紹了Java判斷字符串為空、字符串是否為數(shù)字,其中數(shù)字的判斷介紹了3種方法,需要的朋友可以參考下
    2014-06-06
  • 利用Maven實(shí)現(xiàn)將代碼打包成第三方公共jar包

    利用Maven實(shí)現(xiàn)將代碼打包成第三方公共jar包

    在項(xiàng)目開發(fā)過程中,我們經(jīng)常需要將一些公共方法提取出來,然后單獨(dú)封裝成一個(gè)第三方公共jar包,采用普通的方式打包后的jar,依賴的工程執(zhí)行編譯時(shí),卻提示找不到對(duì)應(yīng)的依賴包,那么如何將工程打包為可執(zhí)行jar包呢?下面向大家分享三種方法
    2022-10-10
  • SpringMVC文件上傳的配置實(shí)例詳解

    SpringMVC文件上傳的配置實(shí)例詳解

    本文通過實(shí)例代碼給大家介紹SpringMVC文件上傳的配置相關(guān)內(nèi)容,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧
    2016-05-05
  • Java線程代碼的實(shí)現(xiàn)方法

    Java線程代碼的實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄狫ava線程代碼的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • 基于Java SSM實(shí)現(xiàn)Excel數(shù)據(jù)批量導(dǎo)入

    基于Java SSM實(shí)現(xiàn)Excel數(shù)據(jù)批量導(dǎo)入

    這篇文章主要為大家詳細(xì)介紹了基于Java SSM如何實(shí)現(xiàn)excel數(shù)據(jù)批量導(dǎo)入,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • 分享幾個(gè)寫簡潔java代碼的小技巧

    分享幾個(gè)寫簡潔java代碼的小技巧

    成為一個(gè)優(yōu)秀的Java程序員,有著良好的代碼編寫習(xí)慣是必不可少的,下面這篇文章主要給大家介紹了關(guān)于寫java代碼的小技巧,文中通過圖文以及實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • Java Iterator迭代器與foreach循環(huán)代碼解析

    Java Iterator迭代器與foreach循環(huán)代碼解析

    這篇文章主要介紹了Java-Iterator迭代器與foreach循環(huán),主要包括Iterator迭代器接口的操作方法和foreach 循環(huán)語法解析,需要的朋友可以參考下
    2022-04-04
  • 詳解Java的Proxy動(dòng)態(tài)代理機(jī)制

    詳解Java的Proxy動(dòng)態(tài)代理機(jī)制

    Java有兩種代理方式,一種是靜態(tài)代理,另一種是動(dòng)態(tài)代理。對(duì)于靜態(tài)代理,其實(shí)就是通過依賴注入,對(duì)對(duì)象進(jìn)行封裝,不讓外部知道實(shí)現(xiàn)的細(xì)節(jié)。很多 API 就是通過這種形式來封裝的
    2021-06-06

最新評(píng)論