springboot使用TaskScheduler實現(xiàn)動態(tài)增刪啟停定時任務(wù)方式
TaskScheduler
概述
TaskScheduler是spring 3.0版本后,自帶了一個定時任務(wù)工具,不用配置文件,可以動態(tài)改變執(zhí)行狀態(tài)。也可以使用cron表達式設(shè)置定時任務(wù)。
被執(zhí)行的類要實現(xiàn)Runnable接口
TaskScheduler是一個接口,它定義了6個方法
接口的6種方法
public interface TaskScheduler { /** * 提交任務(wù)調(diào)度請求 * @param task 待執(zhí)行任務(wù) * @param trigger 使用Trigger指定任務(wù)調(diào)度規(guī)則 * @return */ ScheduledFuture schedule(Runnable task, Trigger trigger); /** * 提交任務(wù)調(diào)度請求 * 注意任務(wù)只執(zhí)行一次,使用startTime指定其啟動時間 * @param task 待執(zhí)行任務(wù) * @param startTime 任務(wù)啟動時間 * @return */ ScheduledFuture schedule(Runnable task, Date startTime); /** * 使用fixedRate的方式提交任務(wù)調(diào)度請求 * 任務(wù)首次啟動時間由傳入?yún)?shù)指定 * @param task 待執(zhí)行的任務(wù) * @param startTime 任務(wù)啟動時間 * @param period 兩次任務(wù)啟動時間之間的間隔時間,默認單位是毫秒 * @return */ ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period); /** * 使用fixedRate的方式提交任務(wù)調(diào)度請求 * 任務(wù)首次啟動時間未設(shè)置,任務(wù)池將會盡可能早的啟動任務(wù) * @param task 待執(zhí)行任務(wù) * @param period 兩次任務(wù)啟動時間之間的間隔時間,默認單位是毫秒 * @return */ ScheduledFuture scheduleAtFixedRate(Runnable task, long period); /** * 使用fixedDelay的方式提交任務(wù)調(diào)度請求 * 任務(wù)首次啟動時間由傳入?yún)?shù)指定 * @param task 待執(zhí)行任務(wù) * @param startTime 任務(wù)啟動時間 * @param delay 上一次任務(wù)結(jié)束時間與下一次任務(wù)開始時間的間隔時間,單位默認是毫秒 * @return */ ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay); /** * 使用fixedDelay的方式提交任務(wù)調(diào)度請求 * 任務(wù)首次啟動時間未設(shè)置,任務(wù)池將會盡可能早的啟動任務(wù) * @param task 待執(zhí)行任務(wù) * @param delay 上一次任務(wù)結(jié)束時間與下一次任務(wù)開始時間的間隔時間,單位默認是毫秒 * @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ù)。
請注意,所有與 ThreadPoolTaskScheduler 相關(guān)的線程名稱都將以ThreadPoolTaskScheduler 為前綴。
讓我們實現(xiàn)一個簡單的任務(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)
指定一個觸發(fā)器執(zhí)行定時任務(wù)。可以使用CronTrigger來指定Cron表達式,執(zhí)行定時任務(wù)
如下:使用CronTrigger 來根據(jù) cron 表達式調(diào)度任務(wù),可以使用提供的觸發(fā)器按照某個指定的節(jié)奏或時間表運行任務(wù),在這種情況下,RunnableTask 將在每分鐘的第 10 秒執(zhí)行。
taskScheduler.schedule(new RunnableTask("Cron Trigger"), cronTrigger);
2、schedule(Runnable task, Date startTime);
指定一個具體時間點執(zhí)行定時任務(wù),可以動態(tài)的指定時間,開啟任務(wù),只執(zhí)行一次
如下:配置一個任務(wù)在 1000 毫秒的固定延遲后運行,RunnableTask 將始終在一次執(zhí)行完成和下一次執(zhí)行開始之間運行 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ù),指定一個執(zhí)行周期(毫秒計時)
PS:不管上一個周期是否執(zhí)行完,到時間下個周期就開始執(zhí)行
如下:安排一個任務(wù)以固定的毫秒速率運行,下一個 RunnableTask 將始終在 2000 毫秒后運行,而不管上次執(zhí)行的狀態(tài)如何,它可能仍在運行。
taskScheduler.scheduleAtFixedRate( new RunnableTask("Fixed Rate of 2 seconds") , 2000);
4、scheduleAtFixedRate(Runnable task, Date startTime, long period);
指定時間開始執(zhí)行,循環(huán)任務(wù),指定一個間隔周期(毫秒計時)
PS:不管上一個周期是否執(zhí)行完,到時間下個周期就開始執(zhí)行
如下:使用CronTrigger 來根據(jù) cron 表達式調(diào)度任務(wù),可以使用提供的觸發(fā)器按照某個指定的節(jié)奏或時間表運行任務(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ù),指定一個間隔周期(毫秒計時)
PS:上一個周期執(zhí)行完,等待delay時間,下個周期開始執(zhí)行
如下:配置一個任務(wù)在 1000 毫秒的固定延遲后運行,RunnableTask 將始終在一次執(zhí)行完成和下一次執(zhí)行開始之間運行 1000 毫秒。
taskScheduler.scheduleWithFixedDelay( new RunnableTask("Fixed 1 second Delay"), 1000);
6、scheduleWithFixedDelay(Runnable task, Date startTime, long delay);
指定時間開始執(zhí)行,循環(huán)任務(wù),指定一個間隔周期(毫秒計時)
PS:上一個周期執(zhí)行完,等待delay時間,下個周期開始執(zhí)行
如下:將任務(wù)配置為在給定開始時間的固定延遲后運行,RunnableTask 將在指定的執(zhí)行時間被調(diào)用,其中包括 @PostConstruct 方法開始的時間,隨后延遲 1000 毫秒。
taskScheduler.scheduleWithFixedDelay( new RunnableTask("Current Date Fixed 1 second Delay"), new Date(), 1000);
接口5個實現(xiàn)類
1、ConcurrentTaskScheduler
以當前線程執(zhí)行任務(wù),如果任務(wù)簡單,可以直接使用這個類來執(zhí)行,快捷方便
- 單線程運行
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
以當前線程執(zhí)行任務(wù),是ConcurrentTaskScheduler的子類,添加了JNDI的支持。
和ConcurrentTaskScheduler一樣的用法,需要使用JNDI可以單獨設(shè)置
3、ThreadPoolTaskScheduler
TaskScheduler接口的默認實現(xiàn)類,多線程定時任務(wù)執(zhí)行。可以設(shè)置執(zhí)行線程池數(shù)(默認一個線程)
- 使用前必須得先調(diào)用
initialize()
【初始化方法】 - 有
shutDown()方法
,執(zhí)行完后可以關(guān)閉線程
除實現(xiàn)了TaskScheduler接口中的方法外,它還包含了一些對ScheduledThreadPoolExecutor進行操作的接口,其常用方法如下:
setPoolSize
:設(shè)置線程池大小,最小為1,默認情況下也為1;setErrorHandler
:設(shè)置異常處理器。getScheduledThreadPoolExecutor
:獲取ScheduledExecutor,默認ScheduledThreadPoolExecutor類型。getActiveCount
:獲取當前活動的線程數(shù)execute
: 提交執(zhí)行一次的任務(wù)submit
\submitListenable
:提交執(zhí)行一次的任務(wù),并且返回一個Future對象供判斷任務(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進行調(diào)度時使用
spring boot使用TaskScheduler實現(xiàn)動態(tài)增刪啟停定時任務(wù)
SchedulingConfig:添加執(zhí)行定時任務(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(); // 定時任務(wù)執(zhí)行線程池核心線程數(shù) taskScheduler.setPoolSize(4); taskScheduler.setRemoveOnCancelPolicy(true); taskScheduler.setThreadNamePrefix("TaskSchedulerThreadPool-"); return taskScheduler; } }
ScheduledTask:添加ScheduledFuture的包裝類
ScheduledFuture是ScheduledExecutorService定時任務(wù)線程池的執(zhí)行結(jié)果。
import java.util.concurrent.ScheduledFuture; public final class ScheduledTask { volatile ScheduledFuture<?> future; /** * 取消定時任務(wù) */ public void cancel() { ScheduledFuture<?> future = this.future; if (future != null) { future.cancel(true); } } }
SchedulingRunnable:添加Runnable接口實現(xiàn)類
添加Runnable接口實現(xiàn)類,被定時任務(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("定時任務(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("定時任務(wù)執(zhí)行異常 - bean:%s,方法:%s,參數(shù):%s ", beanName, methodName, params), ex); } long times = System.currentTimeMillis() - startTime; logger.info("定時任務(wù)執(zhí)行結(jié)束 - bean:{},方法:{},參數(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:添加定時任務(wù)注冊類,用來增加、刪除定時任務(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; /** * 添加定時任務(wù)注冊類,用來增加、刪除定時任務(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); // 如果當前包含這個任務(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:校驗Cron表達式的有效性
import org.springframework.scheduling.support.CronExpression; public class CronUtils { /** * 返回一個布爾值代表一個給定的Cron表達式的有效性 * * @param cronExpression Cron表達式 * @return boolean 表達式是否有效 */ public static boolean isValid(String cronExpression) { return CronExpression.isValidExpression(cronExpression); } }
ScheduleResult:添加定時任務(wù)實體類
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表達式 */ private String cronExpression; /** * 狀態(tài)(1正常 0暫停) */ private Integer jobStatus; /** * 備注 */ private String remark; /** * 創(chuàng)建時間 */ private String createTime; /** * 更新時間 */ 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("沒有這個任務(wù)"); return; } //然后判斷是否開啟, 如果開啟的話,現(xiàn)在立即執(zhí)行 startOrStopSchedulerJob(currentSchedule, true); } public void deleteScheduleJob(ScheduleResult scheduleResult) { // 清除這個任務(wù) cronTaskRegistrar.removeCronTask(scheduleResult.getBeanName(), scheduleResult.getMethodName(), scheduleResult.getMethodParams()); // 清除這個任務(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) { // 更新時間 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)換為年-月-日 時:分:秒 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; /** * 測試上傳的用例文件, 獲取詳細執(zhí)行結(jié)果 */ @PostMapping("/add") void executeTestOneFile(@RequestBody ScheduleResult scheduleResult) { boolean valid = CronUtils.isValid(scheduleResult.getCronExpression()); if (valid){ System.out.println("校驗成功, 添加任務(wù)"); scheduleResult.setMethodParams(scheduleResult.getBranch()+scheduleResult.getCaseDir()); scheduleJobService.addScheduleJob(scheduleResult); }else { System.out.println("校驗失敗"); } } @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)在的定時任務(wù)數(shù)量 = " + allTask.size()); System.out.println("現(xiàn)在的定時任務(wù) = " + allTask); return allTask; } }
c1:測試bean
import org.springframework.stereotype.Component; @Component public class c1 { public void test1(String y){ System.out.println("這個是test1的bean : " + y); } public void test2(){ System.out.println("這個是test1的bean中test2方法"); } }
init:項目啟動后的定時任務(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ù)制粘貼,運行
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
利用Maven實現(xiàn)將代碼打包成第三方公共jar包
在項目開發(fā)過程中,我們經(jīng)常需要將一些公共方法提取出來,然后單獨封裝成一個第三方公共jar包,采用普通的方式打包后的jar,依賴的工程執(zhí)行編譯時,卻提示找不到對應(yīng)的依賴包,那么如何將工程打包為可執(zhí)行jar包呢?下面向大家分享三種方法2022-10-10基于Java SSM實現(xiàn)Excel數(shù)據(jù)批量導(dǎo)入
這篇文章主要為大家詳細介紹了基于Java SSM如何實現(xiàn)excel數(shù)據(jù)批量導(dǎo)入,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-11-11Java Iterator迭代器與foreach循環(huán)代碼解析
這篇文章主要介紹了Java-Iterator迭代器與foreach循環(huán),主要包括Iterator迭代器接口的操作方法和foreach 循環(huán)語法解析,需要的朋友可以參考下2022-04-04