在spring boot中,支持多种定时执行模式(cron, fixRate, fixDelay),在Application或者其他Autoconfig上增加
@EnableScheduling注解开启。
然后在指定方法增加@Scheduled注解,如下:
@Scheduled(cron="0 0 0/1 * * ?")
public void updateTime() {
current_log_time_appendix = sdf.format(new Date());
logger.info("日志文件切换, 切换后为:" + current_log_time_appendix);
需要注意的是,如果在多个函数上使用了@Scheduled,那么一定是一个执行完毕,才能排下一个。这往往不是我们想要的效果。此时需要在Scheduling配置类为schedule返回一个预定的线程池,如下:
@Configuration
@EnableScheduling
public class SchedulingConfiguration {
@Bean(destroyMethod = "shutdown")
public Executor taskScheduler() {
return Executors.newScheduledThreadPool(10);
完成之后,多个@Scheduled可以并发执行了,最高并发度是3,但是同一个@Schedule不会并发执行。
除了cron表达式和quartz、es-job以及linux cron等一样灵活外, spring容器托管的定时任务方法能够利用现成的依赖注入体系,例如:
@Scheduled(cron="0 * * * * *") // 表达式也可以通过@Value注入,例如@Scheduled(cron = "${cron_expression}")
public void ss() {
XXXParameter<BaseParameter> param = new TaLiquidateParameter<>();
param.setTenantCode("*");
param.setLongTaCode("F6");
param.setDatabaseNo("1");
BaseParameter data = new BaseParameter();
data.setLiqBatchNo("1");
data.setIoFlow("EXPORTCONDATA");
param.setData(data);
interfaceDataPrepare(param ); // 当前bean的方法,会依赖其它bean
其它的方式就必须通过ApplicationContext取主动lookup的方式获取了。但是它的缺点是不支持集群,此时仍然需要其它控制机制,所以用来做测试或者其它不需要集群的场景是不错的。
各种cron表达式备忘如下:
0 * * * * *
:每分钟(当秒为0的时候)
0 0 * * * *
:每小时(当秒和分都为0的时候)
*/10 * * * * *
:每10秒
0 5/15 * * * *
:每小时的5分、20分、35分、50分
0 0 9,13 * * *
:每天的9点和13点
0 0 8-10 * * *
:每天的8点、9点、10点
0 0/30 8-10 * * *
:每天的8点、8点半、9点、9点半、10点
0 0 9-17 * * MON-FRI
:每周一到周五的9点、10点…直到17点(含)
0 0 0 25 12 ?
:每年12约25日圣诞节的0点0分0秒(午夜)
0 30 10 * * ? 2016
:2016年每天的10点半
其中的?
在用法上其实和*
是相同的。但是*
语义上表示全匹配,而?
并不代表全匹配,而是不关心。比如对于0 0 0 5 8 ? 2016
来说,2016年8月5日是周五,?
表示我不关心它是周几。而0 0 0 5 8 * 2016
中的*
表示周一也行,周二也行……语义上和2016年8月5日冲突了,你说谁优先生效呢。
不记得也没关系,记住Cron Maker也可以,它可以在线生成cron表达式。
同一个task,如果前一个还没跑完后面一个就不会触发,这没有问题。但是不同的task也不能同时运行就不太合理了。不过其实是scheduler的默认线程数为1的缘故。
解决方法1:如下配置pool-size,但这样会导致同一个task前一个还没跑完后面又被触发的问题。
<task:scheduler id="myScheduler1"/>
<task:scheduler id="myScheduler2"/>
<task:scheduled-tasks scheduler="myScheduler1">
<task:scheduled ref="doSomethingTask" method="doSomething" cron="${0 * * * * *}"/>
</task:scheduled-tasks>
<task:scheduled-tasks scheduler="myScheduler2">
<task:scheduled ref="doOtherThingTask" method="doOtherThing" cron="${0 * * * * *}"/>
</task:scheduled-tasks>