SpringBoot实现定时任务

一、静态定时任务

静态定时任务主要是通过 @Scheduled来实现的,我们先讲解一下这个注解里面的属性。

属性说明
cron使用cron表达式来指定该方法的执行周期
zone时区,一般不用管
fixedDelay指定多少时间内执行一次,如果上一次定时任务没有执行完,则会等待执行完。
fixedDelayString和fixedDelay意思一样,格式是字符串类型
fixedRate指定多少时间内执行一次,如果上一次定时任务没有执行完,则不会等待。
fixedRateString和fixedRate意思一样,格式是字符串类型
initialDelay项目启动完后等待多久后再立即执行
initialDelayString和initialDelay意思一样,格式是字符串类型
timeUnit时间单位,默认毫秒

注意:除了zone和timeUnit,其他属性只能存在一个,不推荐使用fixedRate因为会产生定时任务重复执行问题。

1、启动类加注解

import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling

2、编写定时任务类

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

import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class Test {
    @Scheduled(cron = "0/5 * * * * ?")
    //也可以写成多少毫秒执行一次
    //@Scheduled(fixedRate = 5000)
    public void test(){
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        System.out.println("当前时间"+sdf.format(new Date()));
    }
}

cron表达式在线生成地址:https://cron.qqe2.com/

上面的这种定时任务有很多弊端:比如,修改了cron表达式需要重启,无法停止、修改添加和删除下面我就来讲一下SpringBoot的动态定时任务

二、动态定时任务

1、启动类加注解

import org.springframework.scheduling.annotation.EnableScheduling;

@EnableScheduling

2、编写任务管理类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledFuture;

/**
 * @author hq
 * @date: 2022/5/19 13 57 10
 */
@Component
public class JobManager {
    @Autowired
    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    Map<String, ScheduledFuture<?>> map = new HashMap<>();

    /**
     * 停止定时任务
     */
    public int stopTask(String jobName) {
        ScheduledFuture<?> future = map.get(jobName);
        if (future != null) {
            future.cancel(true);
            return 1;
        }
        return 0;
    }

    /**
     * 添加定时任务
     *
     * @param jobName  任务名
     * @param runnable 执行的类
     * @param cron     cron表达式
     */
    public void addTask(String jobName, Runnable runnable, String cron) {
        ScheduledFuture<?> future = threadPoolTaskScheduler.schedule(runnable, new CronTrigger(cron));
        map.put(jobName, future);
    }

    /**
     * 删除定时任务
     *
     * @param jobName
     */
    public int deleteTask(String jobName) {
        ScheduledFuture<?> future = map.get(jobName);
        if (future != null) {
            future.cancel(true);
            map.remove(jobName);
            return 1;
        }
        return 0;
    }


    /**
     * 修改定时任务
     *
     * @param cron
     */
    public int updateTask(String jobName,Runnable runnable,String cron) {
        ScheduledFuture<?> future = map.get(jobName);
        if (future != null) {
            future.cancel(true);
            //重新设置时间格式需符合cron表达式
            future = threadPoolTaskScheduler.schedule(runnable, new CronTrigger(cron));
            map.put(jobName, future);
            return 1;
        }
        return 0;
    }

}

3、编写需要执行的类

import java.text.SimpleDateFormat;
import java.util.Date;

public class MyRunnable1 implements Runnable{
    @Override
    public void run() {
        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        System.out.println("任务当前时间"+sdf.format(new Date()));
    }
}

注:必须要实现Runnable接口

4、编写测试类

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Test {
    @Autowired
    private JobManager jobManager;

    /**
     *  添加定时任务
     * @param jobName 任务名
     * @param path 需要执行的类的路径(需要实现Runnable接口)
     * @param cron cron表达式
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    @RequestMapping("/addTask")
    public void addTask(String jobName, String path, String cron) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class clazz = Class.forName(path);
        jobManager.addTask(jobName, (Runnable) clazz.newInstance(), cron);
    }

    /**
     * 删除任务
     *
     * @param jobName
     */
    @DeleteMapping("deleteTask")
    public void deleteTask(String jobName) {
        jobManager.deleteTask(jobName);
    }

    /**
     * 修改任务
     * @param jobName 任务名
     * @param path 需要执行的类的路径(需要实现Runnable接口)
     * @param cron cron表达式
     * @throws ClassNotFoundException
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    @GetMapping("/updateTask")
    public void updateTask(String jobName,String path,String cron) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class clazz = Class.forName(path);
        jobManager.updateTask(jobName,(Runnable) clazz.newInstance(), cron);
    }

    /**
     * 停止定时任务
     **/
    @RequestMapping("/stopTask")
    public void stopTask(String jobName) {
        jobManager.stopTask(jobName);
    }
}

虽然这种方式可以实现定时任务的增删改查,但功能还是有些不全,远不如专业的定时任务框架功能强大 ,比如xxl-job和Quartz。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值