springboot实现定时任务常用的2种方式

前言

在业务中,经常需要使用到定时任务做一些逻辑,比如数据批量定时备份、定时清理脏数据等,这种情况下就需要使用到定时任务进行任务调度,下面介绍两种常见的使用方式

方式1:@Scheduled

这种方式最简单,也最灵活,只需要将某个任务类以bean的形式注入到spring容器中进行管理即可

@Component
@EnableScheduling
public class ScheduleTaskTest {

    @Autowired
    private UnionTaskService unionTaskService;

    @Scheduled(cron = "0/10 * * * * *")
    public void getUnionTasks(){
        List<UnionTask> unionTasks = unionTaskService.getAllPassTasks();
        System.out.println("获取到的任务数量是:" + unionTasks.size() );
    }
    
}

但是这种方式有一个缺点,就是cron表达式需要指定,也就是提前写好,其他的业务逻辑处理和正常的业务逻辑一样处理,比如上述案例中,我们每隔10秒取一次数据,效果如下:

在这里插入图片描述

方式2:Spring Task

上面这种方式提到,cron表达式的值需要写死,因此在某些情况下可能无法达到定时任务的动态配置效果,因此就需要某种方式可以动态传入cron的值,以便支持动态配置以及定时任务的定制化,于是可以考虑使用Spring Task

仍以上述代码的业务背景,代码如下:

package com.sx.job.task;

import com.sx.job.entity.UnionTask;
import com.sx.job.service.UnionTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import java.util.Date;
import java.util.List;

/**
 * 支持外部配置cron表达式动态获取
 */

@Component
@EnableScheduling
public class TaskCronChange implements SchedulingConfigurer {

    @Autowired
    private UnionTaskService unionTaskService;

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {

        Runnable task = new Runnable() {
            @Override
            public void run() {
                List<UnionTask> resLists= unionTaskService.getAllPassTasks();
                System.out.println("获取到的数据长度为:" + resLists.size());
            }
        };

        Trigger trigger = new Trigger() {
            @Override
            public Date nextExecutionTime(TriggerContext triggerContext) {
                //任务触发,可修改任务的执行周期.
                //每一次任务触发,都会执行这里的方法一次,重新获取下一次的执行时间
                String cron = unionTaskService.getCronTimes();
                CronTrigger trigger = new CronTrigger(cron);
                Date nextExec = trigger.nextExecutionTime(triggerContext);
                return nextExec;
            }
        };

        taskRegistrar.addTriggerTask(task, trigger);
    }

}

从代码可以看到,cron表达式是从外部传入的,也就是可以提前配置好,然后动态传入进来,运行一下,效果如下:
在这里插入图片描述

实现定时任务还有其他的方式,比如jdk自带的timer或者ScheduledExecutorService ,但在业务类型比较简单的情况下,可以考虑使用,比如像timer仅支持间隔执行任务,还有quarz框架,有兴趣的同学可以继续尝试,本篇到此结束,最后感谢观看!

发布了193 篇原创文章 · 获赞 113 · 访问量 23万+

猜你喜欢

转载自blog.csdn.net/zhangcongyi420/article/details/103409387