Spring Scheduled定时任务动态修改cron参数

使用spring @scheduled注解可以方便的设定定时任务,但是对于定时参数需要变化的情况就会很不方便,如果要实现更改定时参数,就要停止服务,更改参数,重新部署。
对于这种需求, 可以利用TaskScheduler借口来实现,实现方法有两种

  • 启动定时,关闭定时,使用新参数启动定时
  • 使用自定义的Trigger启动定时,更改参数
范例代码如下
1
2
3
4
5
6
7
8
9
10
11
package schedule;

import java.util.Date;

public class Say implements Runnable {

@Override
public void run(){
System.out.println("" + new Date() + " hello");
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
【Spring Scheduled定时任务动态修改cron参数】79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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);
returncronStr;
}

@RequestMapping("/changeCronStr5")
@ResponseBody
public String changeCronStr5(){
cronStr = "*/5 * * * * *";
System.out.println("change "+ cronStr);
returncronStr;
}


public static void main(String[] args) {
SpringApplication.run(ScheduleApplication.class, args);
}
}
说明 threadPoolTaskScheduler.shutdown(); 会抛出异常
@PostConstruct 在依赖注入完成后,进行调用
使用
{ sartcron(); }

会产生空指针异常,以为依赖注入为完成.
@PostConstruct还可以使用BeanPostProcessor的功能来完成.
或使用
1
public class StartupListener implements ApplicationListener

监听事件.
参考
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调度器

    推荐阅读