Spring Boot 实现定时任务

1. 启用定时任务支持

首先,需要在 Spring Boot 应用的主类或者任何配置类中添加 @EnableScheduling 注解,以启用定时任务支持。

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

2. 创建定时任务方法

接下来,可以在任意的 Spring Bean(通常是一个 @Service@Component)中创建一个使用 @Scheduled 注解的方法。该方法会根据指定的时间间隔或触发条件自动执行。

2.1 使用 @Scheduled 注解

@Scheduled 注解支持多种形式的时间配置:

  • fixedRate:按照固定的时间间隔(以毫秒为单位)执行,任务开始时计算间隔。
  • fixedDelay:按照固定的延迟(以毫秒为单位)执行,任务完成后计算间隔。
  • cron:使用 Cron 表达式指定执行时间。

示例代码:

java 复制代码
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyScheduledTasks {

    // 每隔5秒执行一次
    @Scheduled(fixedRate = 5000)
    public void executeTaskWithFixedRate() {
        System.out.println("Task executed at fixed rate: " + System.currentTimeMillis());
    }

    // 上一个任务完成后5秒执行
    @Scheduled(fixedDelay = 5000)
    public void executeTaskWithFixedDelay() {
        System.out.println("Task executed with fixed delay: " + System.currentTimeMillis());
    }

    // 每天早上8点执行
    @Scheduled(cron = "0 0 8 * * ?")
    public void executeTaskWithCronExpression() {
        System.out.println("Task executed using cron expression: " + System.currentTimeMillis());
    }
}

3. 配置 @Scheduled 参数

Spring Boot 中的 @Scheduled 注解支持配置文件中的参数,这样可以灵活地修改定时任务的执行间隔或时间,而无需修改代码。

示例:

application.propertiesapplication.yml 中定义参数:

properties 复制代码
myapp.scheduling.fixed-rate=5000
myapp.scheduling.cron=0 0 8 * * ?

然后在代码中使用 @Value 注解注入这些参数:

java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class MyScheduledTasks {

    @Value("${myapp.scheduling.fixed-rate}")
    private long fixedRate;

    @Value("${myapp.scheduling.cron}")
    private String cronExpression;

    @Scheduled(fixedRateString = "${myapp.scheduling.fixed-rate}")
    public void executeTaskWithFixedRate() {
        System.out.println("Task executed at fixed rate: " + System.currentTimeMillis());
    }

    @Scheduled(cron = "${myapp.scheduling.cron}")
    public void executeTaskWithCronExpression() {
        System.out.println("Task executed using cron expression: " + System.currentTimeMillis());
    }
}

总结

Spring Boot 是基于Spring框架的一个开发框架,它提供了一种简化的方式来开发独立的、独立的、可执行的Spring应用程序。在Spring Boot中实现定时任务可以帮助我们在特定的时间间隔内执行一些特定的任务。本文将以层级的方式总结Spring Boot实现定时任务的相关知识。

  1. 理解定时任务 定时任务是在特定的时间间隔内执行某个任务的机制。Spring Boot提供了一个注解@EnableScheduling,可以开启定时任务的支持。使用该注解后,只需要在任意一个Spring Bean的方法上添加注解@Scheduled,即可定义一个定时任务。

  2. 注解@Scheduled @Scheduled可以用于标记一个方法是一个定时任务。它可以接受多个参数来指定任务的执行时间。其中常用的参数有:

  • fixedRate: 指定任务的执行频率,单位是毫秒。例如,@Scheduled(fixedRate = 1000)表示任务每秒执行一次。
  • fixedDelay: 指定任务之间的延迟时间,单位是毫秒。例如,@Scheduled(fixedDelay = 1000)表示任务执行完毕后,延迟1秒再执行下一次任务。
  • cron: 使用Cron表达式来定义任务的执行时间。例如,@Scheduled(cron = "0 0 0 * * ?")表示每天凌晨零点执行任务。
  1. 定时任务的执行 定时任务默认是在Spring Boot应用程序的启动时自动执行的。可以通过设置参数spring.task.scheduling.enabled=false来禁用自动执行。如果需要在特定的时间启动定时任务,可以使用注解@PostConstruct来标记一个方法,在该方法中手动启动定时任务。例如:
java 复制代码
@Component
public class MyTask {
    @PostConstruct
    public void init() {
        // 手动启动定时任务
    }

    @Scheduled(fixedRate = 1000)
    public void doTask() {
        // 定时任务的执行逻辑
    }
}
  1. 定时任务的线程池 Spring Boot使用一个线程池来执行定时任务,默认线程池大小为1。如果有大量的定时任务,并发执行任务的能力可能会有所不足。可以通过设置参数spring.task.scheduling.pool.size来调整线程池的大小。例如,设置spring.task.scheduling.pool.size=10表示线程池大小为10。

  2. 异步定时任务 定时任务默认是同步执行的,即任务的执行会阻塞其他任务的执行。如果有需要并发执行的任务,可以使用注解@Async将定时任务标记为异步执行。例如:

java 复制代码
@Component
public class MyTask {
    @Async
    @Scheduled(fixedRate = 1000)
    public void doTask() {
        // 异步执行的定时任务
    }
}

需要注意的是,使用@Async注解的方法必须在一个被@Configuration注解的类中,并且该类必须被@EnableAsync注解开启异步支持。

  1. 定时任务的异常处理 定时任务的执行过程中可能会出现异常。Spring Boot提供了一个接口SchedulingConfigurer,可以用来配置定时任务的异常处理器。可以通过实现该接口并重写configureTasks方法来自定义异常处理逻辑。例如:
java 复制代码
@Configuration
@EnableScheduling
public class MyTaskConfig implements SchedulingConfigurer {
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskExecutor());
    }

    @Bean(destroyMethod = "shutdown")
    public Executor taskExecutor() {
        return Executors.newScheduledThreadPool(10);
    }
}

在重写的configureTasks方法中,可以通过taskRegistrar.setScheduler方法来设置定时任务的线程池。在上述示例中,使用了Executors.newScheduledThreadPool(10)方法来创建一个线程池,大小为10。

相关推荐
吃海鲜的骆驼几秒前
服务异步通讯与RabbitMQ
java·分布式·后端·rabbitmq
m0_748233642 分钟前
RabbitMQ 进阶
android·前端·后端
羱滒4 分钟前
sql调优之数据库开发规范
java·数据库·数据库开发
m0_7482386311 分钟前
Spring Boot项目接收前端参数的11种方式
前端·spring boot·后端
Forget the Dream33 分钟前
设计模式之责任链模式
java·c++·设计模式·责任链模式
jonyleek36 分钟前
「JVS更新日志」低代码、企业会议、智能BI、智能排产2.26更新说明
java·大数据·低代码·数据分析·软件需求
计算机小白一个1 小时前
蓝桥杯 Java B 组之最短路径算法(Dijkstra、Floyd-Warshall)
java·数据结构·算法·蓝桥杯
曼岛_1 小时前
[密码学实战]Java实现SM4加解密(ecb,cbc)及工具验证
java·密码学
菜鸟阿达1 小时前
spring boot 2.7 + seata +微服务 降级失败问题修复
spring boot·后端·微服务
清河__1 小时前
【Go】十七、grpc 服务的具体功能编写
开发语言·后端·golang