Spring動態修改時間定時器
阿新 • • 發佈:2018-12-21
採用註解的方式來進行動態修改時間。
首先編寫Spring-timer.xml
檔案。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd"> <context:annotation-config/> <!-- 自動排程需要掃描的包 --> <context:component-scan base-package="cn.gpdi.util"></context:component-scan> <!-- 定時器開關 --> <!-- 可以指定執行執行緒池的初始大小、最大大小 --> <task:executor id="executor" pool-size="5"/> <!-- 排程執行緒池的大小,排程執行緒在被排程任務完成前不會空閒 --> <task:scheduler id="scheduler" pool-size="10"/> <!-- 使用註解驅動 --> <task:annotation-driven executor="executor" scheduler="scheduler"/> </beans>
然後在Spring的配置檔案 Spring-dao.xml
中引入定時器的配置檔案
<!-- 引入Spring定時器配置檔案 -->
<import resource="classpath:spring/spring-timer.xml"/>
編寫定時類
package cn.gpdi.util; import org.apache.log4j.Logger; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * @author Rowe.青衫(qq:1635936133) * @date 2018-11-14. */ @Component public class ScheduledTest { private static Logger logger = Logger.getLogger(ScheduledTest.class); /** * 每5秒執行一次 * cron:表示式控制 */ @Scheduled(cron = "0/5 * * * * ? ") public void print() { DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); logger.debug(" == 定時任務執行 == " + sdf.format(new Date())); } }
這樣簡單的spring定時器就完成了。因為我第一次嘗試的時候報了個debug的錯在我解決了之後想重現發現重現不了了(找不到scheduledExecutorService
這個bean)。我把這個bean寫在了動態定時器裡面了,有詳細的註解。
實現動態的定時器。
package cn.gpdi.util; import org.apache.log4j.Logger; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Lazy; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.SchedulingConfigurer; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.scheduling.config.ScheduledTaskRegistrar; import org.springframework.scheduling.support.CronTrigger; import org.springframework.stereotype.Component; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; /** * 使用Spring註解定時器任務 * * @author Rowe.青衫(qq:1635936133) * @date 2018-11-12. */ @Lazy(false) @Component @EnableScheduling @Configuration public class ScheduledConfig implements SchedulingConfigurer { private static Logger logger = Logger.getLogger(ScheduledConfig.class); /** * 動態定時器預設時間為5秒鐘 */ private static String cron = "0/5 * * * * ?"; public static void setCron(String cron) { ScheduledConfig.cron = cron; } /** * Spring的定時任務排程器會嘗試獲取一個註冊過的task scheduler來做任務排程, * 它會嘗試通過BeanFactory.getBean的方法來獲取一個註冊過的scheduler bean, * 獲取的步驟如下: * 1.嘗試從配置中找到一個TaskScheduler Bean * 2.尋找ScheduledExecutorService Bean * 3.使用預設的scheduler * 前兩步,如果找不到的話,就會以debug的方式丟擲異常 * 解決辦法: * 1.log4j配置改info(當做沒看到) * 2.在容器中新增這個Bean(這裡使用程式碼來進行配置) * * @return TaskScheduler */ @Bean public TaskScheduler scheduledExecutorService() { ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler(); scheduler.setPoolSize(8); scheduler.setThreadNamePrefix("scheduled-thread-"); return scheduler; } /** * 啟動時執行一次,之後每天執行一次 * cron:表示式控制 */ @Scheduled(cron = "0 0 0 * * ?") public void print() { DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); logger.info(sdf.format(" == 任務每天執行一次 == " + new Date())); } /** * 啟動時執行一次,之後每隔1分鐘執行一次 */ @Scheduled(fixedRate = 1000 * 60 * 1) public void heartbeat() { System.out.println("執行?... " + new Date()); } @Override public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { taskRegistrar.addTriggerTask(new Runnable() { /** * Thread current = Thread.currentThread(); * logger.info("ScheduledTest.executeFileDownLoadTask 定時任務:" + current.getId() + ",name:" + current.getName()); */ @Override public void run() { //邏輯任務 logger.info("cron : " + cron); } }, new Trigger() { /** * * @param triggerContext * @return */ @Override public Date nextExecutionTime(TriggerContext triggerContext) { // 任務觸發,可修改任務的執行週期 CronTrigger trigger = new CronTrigger(cron); Date nextExecutor = trigger.nextExecutionTime(triggerContext); return nextExecutor; } }); } }
最後一個動態的定時器就完成了。當需要改變定時器的時間的時候只需要簡單的一步把引數set進去就可以了。
ScheduledConfig.setCron(setCron);