Spring Task 定时任务

文章目录

Spring Task 定时任务

在项目开发中,经常需要定时任务来帮助我们来做一些内容,比如定时派息、跑批对账、业务监控等。

实现定时任务有 3 种方式:

  • java 自带的 API:java.util.Timer 类和 java.util.TimerTask 类;

  • Quartz 框架:开源 功能强大 使用起来稍显复杂;

  • Spring 3.0 以后自带了 task 调度工具,也称 Spring Task,它比 Quartz 更加的简单方便。

pom 包配置

pom 包里面只需要引入 SpringBoot Starter 包即可,SpringBoot Starter 包中已经内置了定时的方法。

xml 复制代码
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
</dependency>

启动类开启定时

在启动类上面加上 @EnableScheduling 即可开启定时:

java 复制代码
@SpringBootApplication
@EnableScheduling
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

创建定时任务实现类

使用 SpringBoot 自带的定时非常的简单,只需要在方法上面添加 @Scheduled 注解即可。

定时任务 1:

java 复制代码
@Component
public class SchedulerTask {
    private static final Logger log = LoggerFactory.getLogger(SchedulerTask.class);
    private int count = 0;

    @Scheduled(cron="*/6 * * * * ?")
    private void process() {
        log.info("{}", "this is scheduler task running " + (count++));
    }
}

设置 process() 每隔六秒执行一次,并统计执行的次数。

我们还有另外的一种方案来设置,固定时间周期执行方法。

定时任务 2:

java 复制代码
@Component
public class Scheduler2Task {
    private static final Logger log = LoggerFactory.getLogger(Scheduler2Task.class);
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

    @Scheduled(fixedRate = 6000)
    public void reportCurrentTime() {
        log.info("{}", "现在时间:" + dateFormat.format(new Date()));
    }
}

启动项目之后,就会在控制台看到打印的结果。

结果如下:

复制代码
INFO [   scheduling-1] com.example.timingtask.Scheduler2Task    : 现在时间:20:12:02
INFO [   scheduling-1] com.example.timingtask.SchedulerTask     : this is scheduler task running 0
INFO [   scheduling-1] com.example.timingtask.Scheduler2Task    : 现在时间:20:12:08
INFO [   scheduling-1] com.example.timingtask.SchedulerTask     : this is scheduler task running 1
INFO [   scheduling-1] com.example.timingtask.Scheduler2Task    : 现在时间:20:12:14
INFO [   scheduling-1] com.example.timingtask.SchedulerTask     : this is scheduler task running 2

说明两个方法都按照固定 6 秒的频率来执行。

参数说明

@Scheduled 参数可以接受两种定时的设置,一种是我们常用的 cron="*/6 * * * * ?",一种是 fixedRate = 6000,两种都可表示固定周期执行定时任务。

fixedRate 说明

  • @Scheduled(fixedRate = 6000) : 上一次开始执行时间点之后 6 秒再执行。
  • @Scheduled(fixedDelay = 6000) : 上一次执行完毕时间点之后 6 秒再执行。
  • @Scheduled(initialDelay=1000, fixedRate=6000) : 第一次延迟 1 秒后执行,之后按 fixedRate 的规则每 6 秒执行一次。

cron 说明

复制代码
用来配置定时任务的时间表达式,通常用于在Unix/Linux系统中设置定时任务。
在Java应用程序中,Cron表达式也被广泛使用,比如在Quartz调度框架中用来配置定时任务的触发时间。

Cron表达式由7个字段组成,分别表示秒、分钟、小时、日期、月份、星期和年(可选)。
每个字段可以包含多个取值,以逗号分隔,或者可以使用通配符和范围来表示时间。以下是Cron表达式的基本格式:

plaintext
秒 分 时 日 月 星期 年
其中,各字段的取值范围如下:

秒(0-59)、分钟(0-59)、小时(0-23)、日期(1-31)、月份(1-12或者 JAN-DEC)
星期(0-7或者 SUN-SAT,0和7都代表星期日)、年(可选,留空表示每年)。

以下是一些常见的Cron表达式示例:
0 0 12 * * ?:每天中午12点触发
0 0/5 * * * ?:每隔5分钟触发
0 0 8-10 * * ?:每天上午8点至10点之间每小时触发
0 0 6,18 * * ?:每天早上6点和晚上6点触发
0 0 9 ? * MON-FRI:周一至周五的早上9点触发

并行任务

了解

之前的的定时任务都是串行执行的。所谓串行执行指的是只由一个线程来执行任务。除了这种方式 Spring Task 还支持并行执行任务,即由多个线程来执行不同的任务。

要实现这样的功能,你需要去进行额外的配置:

java 复制代码
@Configuration
@EnableScheduling
public class TimingTaskConfig implements SchedulingConfigurer, AsyncConfigurer {

    // 线程池线程数量
    private static final int corePoolSize = 5;

    @Bean
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.initialize(); // 初始化线程池
        scheduler.setPoolSize(corePoolSize); // 线程池容量
        return scheduler;
    }

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setTaskScheduler(taskScheduler());
    }

    @Override
    public Executor getAsyncExecutor() {
        return taskScheduler();
    }

    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return null;
    }
}

注意,这时 @EnableScheduling 注解标注在了这个配置类上,因此,Spring Boot 的入口类上就不再需要标注它了。(当然,你硬要把它标注在入口类上其实也可以)。

其它的相关代码无需修改,运行项目你会看到类似如下的日志输出:

复制代码
INFO [taskScheduler-1] com.example.timingtask.Scheduler2Task    : 现在时间:20:08:57
INFO [taskScheduler-1] com.example.timingtask.SchedulerTask     : this is scheduler task running 0
INFO [taskScheduler-2] com.example.timingtask.Scheduler2Task    : 现在时间:20:09:03
INFO [taskScheduler-3] com.example.timingtask.SchedulerTask     : this is scheduler task running 1
INFO [taskScheduler-1] com.example.timingtask.Scheduler2Task    : 现在时间:20:09:09
INFO [taskScheduler-4] com.example.timingtask.SchedulerTask     : this is scheduler task running 2
相关推荐
Darkdreams8 分钟前
SpringBoot项目集成ONLYOFFICE
java·spring boot·后端
bropro26 分钟前
【Spring Boot】Spring AOP中的环绕通知
spring boot·后端·spring
lhbian26 分钟前
【Spring Cloud Alibaba】基于Spring Boot 3.x 搭建教程
java·spring boot·后端
luom010235 分钟前
springcloud springboot nacos版本对应
spring boot·spring·spring cloud
IT_陈寒40 分钟前
Redis性能提升3倍的5个冷门技巧,90%开发者都不知道!
前端·人工智能·后端
LucianaiB41 分钟前
OpenClaw 安装后必看!你真的会科学养虾吗?第1天和第47天的Openclaw有什么区别?
后端
寻见9032 小时前
智能体开发_07Function Calling道法术器拆解,一文搞懂大模型如何“做事”
人工智能·后端·ai编程
奋斗小强2 小时前
数据库优化:从慢查询到索引,让系统快 10 倍
后端
重庆穿山甲2 小时前
从零到精通:OpenClaw完整生命周期指南
前端·后端·架构
架构师沉默2 小时前
AI 真的会取代程序员吗?
java·后端·架构