当前位置: 首页 > news >正文

基于@Scheduled注解(静态配置)实现定时任务

前言

  • 在Spring Boot中,定时任务通过简单的注解即可实现周期性任务的自动执行
  • 常用于数据统计、定时清理、通知推送等场景。

实现流程

1.启用定时任务
  • 在主类或配置类添加 @EnableScheduling 注解
@SpringBootApplication
@EnableScheduling // 开启定时任务支持
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
2.定义定时任务类
@Component
public class SimpleScheduledTask {
    
    // 每5秒执行一次(固定速率,从任务开始时间算间隔)
    @Scheduled(fixedRate = 5000)
    public void task1() {
        System.out.println("Fixed Rate Task: " + LocalDateTime.now());
    }

    // 每3秒执行一次(固定延迟,从任务结束时间算间隔)
    @Scheduled(fixedDelay = 3000)
    public void task2() {
        System.out.println("Fixed Delay Task: " + LocalDateTime.now());
    }

    // 每天10:00执行(Cron表达式)
    @Scheduled(cron = "0 0 10 * * ?")
    public void task3() {
        System.out.println("Cron Task: " + LocalDateTime.now());
    }
}
  • 关键参数说明
    在这里插入图片描述
  • Cron表达式格式【可通过相关网站设置并生成】
秒(0-59) 分(0-59) 时(0-23) 日(1-31) 月(1-12) 周(0-7,0和7均为周日)

注意事项

  • 需要在启动类上添加注解支持@EnableScheduling,负责定时任务失效。
    在这里插入图片描述

效果【观察输出日志】

在这里插入图片描述

拓展【其他实现方式】

1.动态任务配置(基于接口 SchedulingConfigurer)

  • A.适用场景:
    • 需要从数据库或配置文件动态加载任务配置
    • 支持运行时动态增删改任务
  • B.实现步骤
  • (1)创建动态任务配置类:
@Configuration
@EnableScheduling
public class DynamicScheduledConfig implements SchedulingConfigurer {

    @Autowired
    private TaskConfigRepository taskConfigRepository; // 假设从数据库读取任务配置

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        // 动态加载任务配置
        List<TaskConfig> tasks = taskConfigRepository.findAllEnabledTasks();
        tasks.forEach(task -> {
            Runnable runnable = () -> executeTask(task);
            Trigger trigger = context -> {
                String cron = task.getCronExpression();
                return new CronTrigger(cron).nextExecutionTime(context);
            };
            taskRegistrar.addTriggerTask(runnable, trigger);
        });
    }

    private void executeTask(TaskConfig task) {
        System.out.println("执行动态任务: " + task.getName() + ", 时间: " + LocalDateTime.now());
    }
}
  • (2)数据库实体示例:
@Entity
public class TaskConfig {
    @Id
    private String id;
    private String name;
    private String cronExpression;
    private boolean enabled;
    // Getters and Setters
}

2.多线程定时任务

  • 解决单线程阻塞问题:默认情况下,@Scheduled 任务在单线程中串行执行。若需并行执行:
  • 配置线程池
@Configuration
public class AsyncScheduledConfig {

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5); // 线程池大小
        scheduler.setThreadNamePrefix("scheduled-task-");
        scheduler.setAwaitTerminationSeconds(60);
        scheduler.setWaitForTasksToCompleteOnShutdown(true);
        return scheduler;
    }
}
  • 异步任务实例
@Component
public class AsyncScheduledTask {

    // 异步 + 定时任务
    @Async("taskExecutor") // 指定自定义线程池
    @Scheduled(fixedRate = 5000)
    public void asyncTask() {
        System.out.println("异步任务线程: " + Thread.currentThread().getName());
    }
}

总结

在这里插入图片描述

  • 实际开发中,推荐优先使用 @Scheduled 注解快速实现简单任务,复杂场景结合动态配置和线程池优化。
  • 生产环境务必添加任务监控和分布式锁机制。

相关文章:

  • SQL调优
  • 搭建PG库和安装pgvector、pgRouting插件
  • uniapp 微信小程序图片下载保存功能
  • TypeScript 泛型 < T > 从入门到精通
  • 可视化图解算法:删除有序(排序)链表中重复的元素
  • 基于AOP注解+Redisson实现Cache-Aside缓存模式实战
  • 春日焕新居:约克VRF中央空调,科技赋能,带你开启健康呼吸新时代
  • 力扣题目分享:只出现1次的数字I II III(位运算版)
  • 宝塔docker flarum默认登录账号密码,crazymax/flarum镜像默认登录账号密码
  • 蓝桥杯算法题分享(二)
  • 从 Copilot 到垂直工具:AI 编程的 “专精特新“ 进化论
  • 用python写网络爬虫
  • 如何用Spring AI构建MCP Client-Server架构
  • 动手实践:单机安装高性能列式存储数据库ClickHouse
  • 根据模板将 Excel 明细数据生成 PDF 文档 | PDF实现邮件合并功能
  • 大数据学习(85)-Flume详解
  • mysql学习-索引规则
  • 蓝桥杯 回文字符串
  • 09_JavaScript数据操作方法_数组2
  • 基于Zookeeper的微服务配置管理与灰度发布实战指南
  • 资深娱乐策划人、导演马勇逝世,终年51岁
  • 西尔艾力·外力任吐鲁番市副市长、代理市长,朱继坤任副市长
  • 福州市委副书记、福州新区党工委书记陈云水转任三明市政协党组书记
  • 港股上市首日大涨,宁德时代“新动力”何在?曾毓群详谈零碳科技布局
  • 广东茂名信宜出现龙卷,一家具厂铁皮房受损
  • 王楚钦球拍受损,乒乓球裁判揭秘大赛球拍检测