Spring6.x对调度和异步执行的注解支持示例详解
1 启用Scheduling注解
Spring为任务调度和异步方法执行提供注解支持。
要启用 @Scheduled
和 @Async
,在 @Configuration
类(或者在启动类)添加 @EnableScheduling
和 @EnableAsync
,如下:
1 2 3 4 5 6 7 8 9 10 | @SpringBootApplication (exclude = { DataSourceAutoConfiguration. class , }) @EnableScheduling public class RoadSyncApplication { public static void main(String[] args) { SpringApplication.run(RoadSyncApplication. class , args); } } |
你可以为你的应用程序选择相关的注解。例如,如果你只需要支持 @Scheduled
,可以省略 @EnableAsync
。对于更细粒度的控制,你还可以分别实现 SchedulingConfigurer
接口和 AsyncConfigurer
接口。有关完整详细信息,请参阅 SchedulingConfigurer 和 AsyncConfigurer javadoc。
默认处理 @Async
注解的建议模式是 proxy
,它仅允许通过代理拦截调用。使用这种方式无法拦截同一类中的本地调用。 对于更高级的拦截模式,请考虑切换到 aspectj
模式与编译时织入或加载时织入结合使用。
2 @Scheduled 注解
可将 @Scheduled
注解以及触发元数据添加到方法中。
2.1 fixedDelay
如下方法每5000ms执行一次,采用固定延迟,即周期从每次先前调用的【完成时间】开始测量。
默认,固定延迟、固定速率和初始延迟的值将使用ms作时间单位。如想用不同时间单位,如s或min,可在 @Scheduled
配置 timeUnit
属性:
2.2 fixedRate
如需固定速率执行,使用 fixedRate
属性。下面的方法每五秒(从每次【调用的开始时间】间隔测量)执行一次:
固定延迟、固定速率的任务,可通过指示等待的时间量来指定初始延迟,然后再执行方法的第一次调用:
2.3 一次性任务
可只指定通过指示等待执行方法的时间量的初始延迟:
若简单的定期计划不够表达力,可用 cron 表达式:
还可使用 zone
属性指定解析 cron 表达式的时区。
要计划的方法须有 void 返回值,且不接受任何参数。如果方法需要与应用程序上下文中的其他对象交互,那么这些对象通常已经通过依赖注入。
@Scheduled
是可重复注解。如在同一方法上找到几个 scheduled 声明,每个声明都将独立处理,为每个声明触发单独的触发器。因此,这样的共定位计划可并行重叠并立即连续执行多次。请确保你指定的 cron 表达式等不会意外重叠。
Spring Framework 4.3 开始,支持任何范围的 bean 上的 @Scheduled
方法。确保在运行时不初始化同一 @Scheduled
注解类的多个实例,除非你确实希望调度回调到每个这样的实例。
确保不要在使用 @Scheduled
注解并作为常规 Spring bean 注册到容器中的 bean 类上使用 @Configurable
。否则,你将获得双重初始化(一次通过容器,一次通过 @Configurable
方面),其结果是每个 @Scheduled
方法被调用两次。
FAQ
问题
生产用@Scheduled注解写定时任务,5min执行一次:
1 2 3 4 5 | @Scheduled (cron = "0 0/5 * * * ?" ) public void MyTimerJobSchedule() throws Exception { //省略具体业务逻辑 System.out.println( "五分钟执行一次" ); } |
过几天,领导通知说有问题,一查日志,发现是定时任务问题。本来应该是5min跑一次,结果日志发现,每天0点-3点正常,3-10点没执行;一直到10-11点之间才继续跑。
原因
发现可能是定时任务单线程模式导致任务阻塞。
继续分析日志,发现该定时任务的线程号是[Scheduling-1],除了执行自身的任务,还打印了其它定时任务的输出语句。
每天3点前,[Scheduling-1]线程在执行本人写的5min一次的定时任务,3点后,[Scheduling-1]线程会执行另一个比较耗时的定时任务,直到10点后,[Scheduling-1]线程才重新执行5min一次的定时任务。
看来,确实是由于@Scheduled定时任务默认使用单线程模式导致:一旦有一个定时任务比较耗时,就会影响到其它定时任务按时执行。
解决方法
在定时任务加@Async注解,并在启动类增加@EnableAsync注解,使用多线程模式执行定时任务。
参考网址 https://www.jb51.net/program/3058076vb.htm
参考网址中有第二种解决方法,但是已说明不太好用,因此只用第一种解决方法就够了。
以上就是Spring6.x对调度和异步执行的注解支持示例详解的详细内容,更多关于Spring6.x调度异步执行注解的资料请关注脚本之家其它相关文章!
微信公众号搜索 “ 脚本之家 ” ,选择关注
程序猿的那些事、送书等活动等着你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!
相关文章
idea项目启动报错,日志包冲突slf4j和logback冲突问题
遇到SLF4J冲突时,可以尝试移除冲突的绑定或调整项目依赖,具体方法包括删除多余的Logger绑定库,如Logback或Log4j,或在项目配置文件中明确指定使用的日志框架,若使用WebLogic服务器,需在weblogic.xml中进行特定配置,适当调整pom.xml文件中的依赖版本也可能解决问题2024-09-09没有编辑器的环境下是如何创建Servlet(Tomcat+Java)项目的?
今天给大家带来的是关于Java的相关知识,文章围绕着在没有编辑器的环境下如何创建Servlet(Tomcat+Java)项目展开,文中有非常详细的介绍及代码示例,需要的朋友可以参考下2021-06-06
最新评论