在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="scheduler" pool-size="2" />

解决方法2:让任务分别运行在不同的scheduler里。例如:

<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>

spring boot @Scheduled未生效原因以及相关坑、及相对其他定时任务架构的优势的更多相关文章

  1. Spring Boot Actuator未授权访问

    当我们发现某一个网页的logo是一篇叶子或者报错信息如下图所示的话,就可以尝试Spring Boot Actuator未授权访问. /dump - 显示线程转储(包括堆栈跟踪) /autoconfig ...

  2. Spring Boot Scheduled定时任务特性

    SpringBoot中的Scheduled定时任务是Spring Boot中非常常用的特性,用来执行一些比如日切或者日终对账这种定时任务 下面说说使用时要注意的Scheduled的几个特性 Sched ...

  3. spring cloud: 升级到spring boot 2.x/Finchley.RELEASE遇到的坑

    spring boot2.x已经出来好一阵了,而且spring cloud 的最新Release版本Finchley.RELEASE,默认集成的就是spring boot 2.x,这几天将一个旧项目尝 ...

  4. Spring boot redis自增编号控制 踩坑

    近段期间,公司 接手一个订单号生成服务,规则的话已经由项目经理他们规定好了,主要是后面的四位数代表的关于当前订单号已经执行第几个了.而这里面有一个要求就是支持分布式.为了实现这个东西,刚开始我使用了r ...

  5. Spring boot 数据源未配置异常

    问题 在使Springboot自动生成的项目框架时如果选择了数据源,比如选择了mysql,生成项目之后,启动会报一下异常: Description: Cannot determine embedded ...

  6. spring boot 启动慢的原因

    停留在Spring logo那里差不多4分钟 SpringBoot启动慢的原因应该是某些应用占用了spring config server默认的端口8888,然后SpringCloud进程有些引用了s ...

  7. Spring boot @Scheduled(cron = "* * * * * *") cron表达式详解

    //@Scheduled(cron = "0 0/15 * * * ?") //每15分钟触发一次 //@Scheduled(cron = "5/10 * * * * ? ...

  8. spring boot CrossOrigin不生效?

    直接postman, curl, 浏览器访问后端接口, response header是不会自动加上Access-Control-Allow-Origin的. 需要在ajax中调用,客户端reques ...

  9. maven-shade-plugin插件未生效原因分析

    今天在项目的pom文件中引入maven-shade-plugin插件,构建一个uber-jar(包含所有依赖的jar包),但是诡异的事情出现了,执行mvn package后生成的jar包竟然没有包含被 ...

随机推荐

  1. canvas 写一个刮刮乐抽奖

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. Python中self和__init__的含义与使用

    原文地址https://blog.csdn.net/love666666shen/article/details/78189984 Python中的self 在Python中的类Class的代码中,常 ...

  3. unity3d生命周期

  4. php实现记住密码下次自动登陆

    这篇博客里面还写到 实现“记住我的登录状态”的功能方法,简言之,就是对首先对session进行用户信息赋值,检测session,失效后,利用cookie对其赋值: 在实现过程中,根据网上一些代码贴,整 ...

  5. java资料共享

    1.javascript视频教程 链接: http://pan.baidu.com/s/1gd57FVH 密码: d9ei 2.JPA视频教程 链接: http://pan.baidu.com/s/1 ...

  6. c# Mongodb创建自增列

    MongoCollection<BsonDocument> tblCount; if (!db.CollectionExists(tblCountName))            {   ...

  7. sql 将某一列转成字符串并且去掉最后一个逗号

    ) SET @center_JZHW = ( SELECT DISTINCT STUFF( ( SELECT ','''+ qudao+'''' FROM CreatedType WITH ( NOL ...

  8. 10.for

    要遍历一个范围(如数组或表),使用 for 循环.在数组上迭代时,当前数组元素存储在循环变量中.在遍历字典时, index 存储在循环变量中. (in 内容测试) for x in [5, 7, 11 ...

  9. word自动编号后面空格位置太大了

    选择你需要调整的段落.右键点击.选择“调整列表缩进” 然后在弹出的窗口中,第三行的“制表符”改成“空格”即可.或者空格都不需要可以改为“不特别标注”

  10. 反射(I)

    反射获取属性和属性值 let item = DoctorGroup() guard let dic = InterfaceTests.obtainValues(subObject: item) els ...