使用spring @scheduled注解可以方便的設定定時任務,但是對於定時參數需要變化的情況就會很不方便,如果要實現更改定時參數,就要停止服務,更改參數,重新部署。
對於這種需求, 可以利用TaskScheduler借口來實現,實現方法有兩種
- 啟動定時,關閉定時,使用新參數啟動定時
- 使用自定義的Trigger啟動定時,更改參數
范例代碼如下
package schedule;
import java.util.Date;
public class Say implements Runnable {
@Override
public void run(){
System.out.println("" + new Date() + " hello");
}
}
package schedule;
import java.util.Date;
import java.util.concurrent.ScheduledFuture;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@SpringBootApplication
public class ScheduleApplication {
@Autowired
private ThreadPoolTaskScheduler threadPoolTaskScheduler;
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
return new ThreadPoolTaskScheduler();
}
private ScheduledFuture<?> future;
@RequestMapping("/")
@ResponseBody
public String home(){
return "home";
}
///方法一
@RequestMapping("/startCron")
@ResponseBody
public String startCron(){
System.out.println("x0");
//threadPoolTaskScheduler.shutdown();
future = threadPoolTaskScheduler.schedule(new Say(), new CronTrigger("*/5 * * * * *"));
System.out.println("x1");
return "x";
}
@RequestMapping("/stopCron")
@ResponseBody
public String stopCron(){
System.out.println("stop >>>>>");
if(future != null) {
future.cancel(true);
}
//future = threadPoolTaskScheduler.schedule(new Say(), new CronTrigger("*/5 * * * * *"));
System.out.println("stop <<<<<");
return "stop cron";
}
@RequestMapping("/startCron10")
@ResponseBody
public String startCron10(){
System.out.println("x100");
future = threadPoolTaskScheduler.schedule(new Say10(), new CronTrigger("*/12 * * * * *"));
System.out.println("x101");
return "x10";
}
///方法二
private String cronStr = "*/5 * * * * *";
@RequestMapping("/startCron1")
@ResponseBody
public String startCron1(){
System.out.println("startCron1 >>>>");
threadPoolTaskScheduler.schedule(new Say(), new Trigger(){
@Override
public Date nextExecutionTime(TriggerContext triggerContext){
return new CronTrigger(cronStr).nextExecutionTime(triggerContext);
}
});
System.out.println("startCron1 <<<<");
return "*****";
}
@PostConstruct
public void start(){
startCron1();
}
@RequestMapping("/changeCronStr")
@ResponseBody
public String changeCronStr(){
cronStr = "*/12 * * * * *";
System.out.println("change " + cronStr);
return cronStr;
}
@RequestMapping("/changeCronStr5")
@ResponseBody
public String changeCronStr5(){
cronStr = "*/5 * * * * *";
System.out.println("change " + cronStr);
return cronStr;
}
public static void main(String[] args) {
SpringApplication.run(ScheduleApplication.class, args);
}
}
說明 threadPoolTaskScheduler.shutdown();會拋出異常
@PostConstruct 在依賴注入完成后,進行調用
使用
{
sartcron();
}
會產生空指針異常,以為依賴注入為完成.
@PostConstruct還可以使用BeanPostProcessor的功能來完成.
或使用
public class StartupListener implements ApplicationListener<ContextRefreshedEvent>
監聽事件.
參考
Spring/SpringMVC在啟動完成后執行方法
http://blog.csdn.net/renyisheng/article/details/50803875
Spring/SpringMVC在啟動完成后執行方法
http://www.cnblogs.com/itjcw/p/5977911.html
Spring @Scheduled定時任務動態修改cron參數
http://blog.csdn.net/xht555/article/details/53121962
Java 定時任務系列(2)-Spring 定時任務的幾種實現
https://segmentfault.com/a/1190000002504252
Java timer task schedule
http://stackoverflow.com/questions/4044729/java-timer-task-schedule
[Spring筆記]支持注解的Spring調度器
www點
w
2
b
c
點com/article/169011
