spring boot —— 整合Scheduling定时任务

本文深入探讨Spring框架中Spring Task模块的使用方法,包括如何启用任务调度、配置串行和并行任务,以及@Scheduled注解的详细参数说明。通过实例代码展示了固定周期和随机延迟任务的实现。

Spring 3.0后提供Spring Task实现任务调度,支持按日历调度,相比Quartz功能稍简单,但是在开发基本够用,支 持注解编程方式。

使用

启用在spring boot 启动类上添加注解: @EnableScheduling 

串行任务

两个任务方法由一个线程串行执行,方法执行完成task2再执行。 

测试代码:

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * @author LYQ
 * @since 2018/12/19 14:55
 */
@Component
public class TestTask {

    @Scheduled(fixedRate = 3000)//每隔5秒执行一次
    public void task1(){
        System.out.println("定时任务测试1");
    }
}

参数说明:https://www.jianshu.com/p/1defb0f22ed1

并行任务

多个任务由不同的线程在并行执行,互不影响。

@Configuration
@EnableScheduling
public class AsyncTaskConfig implements SchedulingConfigurer, AsyncConfigurer {
    //线程池线程数量
    private int corePoolSize = 5;

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

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

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

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

注意:将@EnableScheduling添加到此配置类上,SpringBoot启动类上不用再添加@EnableScheduling 

@Scheduled 参数说明

1. cron

该参数接收一个cron表达式,cron表达式是一个字符串,字符串以5或6个空格隔开,分开共6或7个域,每一个域代表一个含义。

cron表达式使用占位符

time:
  cron: */5 * * * * *
  interval: 5

    @Scheduled(cron="${time.cron}")
    void testPlaceholder1() {
        System.out.println("Execute at " + System.currentTimeMillis());
    }

    @Scheduled(cron="*/${time.interval} * * * * *")
    void testPlaceholder2() {
        System.out.println("Execute at " + System.currentTimeMillis());
    }

2. zone

时区,接收一个java.util.TimeZone#ID。cron表达式会基于该时区解析。默认是一个空字符串,即取服务器所在地的时区。比如我们一般使用的时区Asia/Shanghai。该字段我们一般留空。

3. fixedDelay

上一次执行完毕时间点之后多长时间再执行。如:

//上一次执行完毕时间点之后10秒再执行 
@Scheduled(fixedDelay = 10000) 

4. fixedDelayString

与 3. fixedDelay 意思相同,只是使用字符串的形式。唯一不同的是支持占位符。如:

//上一次执行完毕时间点之后10秒再执行 
@Scheduled(fixedDelayString = "10000") 

占位符的使用(配置文件中有配置:time.fixedDelay=10000):

    @Scheduled(fixedDelayString = "${time.fixedDelay}")
    void testFixedDelayString() {
        System.out.println("Execute at " + System.currentTimeMillis());
    }

应用
 

注解随机延迟

当有多个节点时不希望它们同时运行。所以我想为初始延迟设置一个随机值,以使它们相互抵消。

import org.springframework.scheduling.annotation.Scheduled; @Scheduled(fixedRate = 600000, initialDelay = <random number between 0 and 10 minutes> ) 

不幸的是,我在这里只能使用常量表达式。有没有其他方法可以解决这个问题?我想到了使用Spring表达式语言。

可以通过Spring Expression Language配置initialDelay:

@Scheduled(fixedRate = 600000, initialDelayString = "#{ T(java.util.concurrent.ThreadLocalRandom).current().nextInt(10*60*1000) }" )


​​​​​​​

### 如何在Spring Boot整合WebSocket并使用定时任务 #### 配置WebSocket支持 为了使应用程序能够利用WebSocket功能,在`pom.xml`文件中引入必要的依赖项[^2]: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> ``` 接着定义一个配置类用于设置WebSocket的支持,这可以通过继承`WebSocketConfigurer`接口并重写相应的方法完成。此过程涉及注册端点以及指定处理器映射规则。 #### 创建WebSocketHandler处理程序 编写自定义的`WebSocketHandler`来管理客户端连接事件(打开、关闭)、异常情况下的响应逻辑以及其他业务操作。此类负责接收来自客户端的消息,并向其发送数据更新通知。 #### 实现调度器执行周期性任务 对于需要定期触发的功能模块来说,可以借助于Java内置的任务计划工具——ScheduledExecutorService或者更简单的@Scheduled注解方式。后者允许开发者直接在方法上声明时间间隔参数从而简化编程模型。 下面是一个例子展示如何结合这两者工作: ```java import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component public class MyMessageScheduler { private final SimpMessagingTemplate template; public MyMessageScheduler(SimpMessagingTemplate template) { this.template = template; } @Scheduled(fixedRate = 5000) void sendPeriodicUpdate() { String content = "This is a periodic message sent every five seconds."; System.out.println("Sending scheduled update..."); template.convertAndSend("/topic/messages", content); } } ``` 上述代码片段展示了怎样每隔五秒推送一条新消息给所有订阅特定主题路径下的在线用户[^1]。 此外还需要确保已激活@EnableScheduling以启用组件扫描机制自动发现带有@Scheduled标记的方法。 最后一步是在前端部分建立监听以便及时接收到服务器发出的通知信息。通常情况下会采用SockJS与STOMP协议组合的形式来进行跨浏览器兼容性的优化[^3]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘彦青-Yannis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值