Spring Boot如何实现定时任务的动态增删启停详解

下面我会详细讲解“Spring Boot如何实现定时任务的动态增删启停详解”的完整攻略。

什么是定时任务?

定时任务(Scheduled Task)是指在指定的时间点或时间间隔内自动执行某个操作的任务。在很多场景下,我们经常需要定时执行某些操作,例如定时清理临时数据、定时发送邮件等。

Spring Boot如何实现定时任务

Spring Boot 提供了标准的方式来支持定时任务的实现,主要借助了 @EnableScheduling 注解和 @Scheduled 注解。

添加依赖

pom.xml 中添加 Spring Boot 定时任务的依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-quartz</artifactId>
</dependency>

启用定时任务

在启动类上添加 @EnableScheduling 注解,启用 Spring Boot 定时任务功能:

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

定义定时任务

定义定时任务使用 @Scheduled 注解,该注解可以标记在方法上,并可以设置定时任务的触发条件,例如:

@Component
public class MyTask {
    @Scheduled(fixedRate = 1000)
    public void doTask() {
        System.out.println("定时任务执行中...");
    }
}

上面的例子中,使用 @Scheduled(fixedRate = 1000) 设置了每隔 1000 毫秒执行一次 doTask 方法,该方法中的代码会在定时任务触发时被执行。

动态增删启停定时任务

通过上述的方式,我们可以实现简单的定时任务功能,但是如何实现动态增删启停定时任务呢?

方式一:使用 TaskScheduler 接口实现动态任务

Spring Boot 为我们提供了 TaskScheduler 接口,可以实现动态添加和删除任务的功能。我们只需要注入该接口的实例,然后借助 ScheduledFuture 对象控制任务的执行即可。

示例代码如下:

@Component
public class DynamicTask {
    @Autowired
    private TaskScheduler taskScheduler;

    private ScheduledFuture<?> future;

    /**
     * 开启任务
     * @param interval 任务间隔,毫秒数
     */
    public void start(long interval) {
        stop();
        this.future = taskScheduler.scheduleAtFixedRate(() -> {
            System.out.println("动态定时任务执行中...");
        }, interval);
    }

    /**
     * 停止任务
     */
    public void stop() {
        if (this.future != null) {
            this.future.cancel(true);
        }
    }
}

在上述代码中,我们定义了 DynamicTask 类,其中 start 方法用于启动任务,接收一个时间间隔参数 interval,该方法会先停止已存在的任务,再根据传入参数启动新任务,任务的执行内容是打印一条日志信息。stop 方法用于停止任务,基于 ScheduledFuture 对象实现。

方式二:使用 Quartz 框架实现动态任务

当具备更高的动态性能力时,我们可以选择使用 Quartz 框架。

在 Spring Boot 中,通过添加 spring-boot-starter-quartz 依赖,并在配置文件中设置各种参数即可使用 Quartz 实现定时任务。

下面是一个使用 Quartz 实现动态增删启停定时任务的示例代码:

@Component
public class DynamicQuartzTask extends QuartzJobBean {
    private static final Logger LOGGER = LoggerFactory.getLogger(DynamicQuartzTask.class);

    private Scheduler scheduler;

    private String schedulerName;

    private String jobName;

    private String groupName;

    private String cronExpression;

    public DynamicQuartzTask(Scheduler scheduler, String schedulerName, String jobName, String groupName, String cronExpression) {
        this.scheduler = scheduler;
        this.schedulerName = schedulerName;
        this.jobName = jobName;
        this.groupName = groupName;
        this.cronExpression = cronExpression;
    }

    /**
     * 启动任务
     * @throws Exception
     */
    public void start() throws Exception {
        // 如果 job 存在,则删除任务
        JobKey key = new JobKey(jobName, groupName);
        if (scheduler.checkExists(key)) {
            scheduler.deleteJob(key);
        }

        // 构造 jobDetail
        JobDetail jobDetail = JobBuilder.newJob(getClass()).withIdentity(jobName, groupName).build();

        // 构造 trigger
        CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, groupName)
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression)).build();

        // 启动定时任务
        scheduler.scheduleJob(jobDetail, trigger);
    }

    /**
     * 停止任务
     * @throws Exception
     */
    public void stop() throws Exception {
        scheduler.deleteJob(new JobKey(jobName, groupName));
    }

    @Override
    public void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        LOGGER.info("动态定时任务执行中...");
    }
}

上述代码中,我们定义了 DynamicQuartzTask 类,构造方法中接收 Scheduler 对象和各种任务相关的参数,使用 checkExists 方法检查任务是否已存在,如果存在则删除任务,接着构造 JobDetailTrigger,最后通过 scheduleJob 方法来启动任务。

具体使用可以参考下面的例子:

@Component
public class ScheduleTaskTest implements CommandLineRunner {

    @Autowired
    private Scheduler scheduler;

    @Autowired
    private DynamicQuartzTask dynamicQuartzTask;

    @Override
    public void run(String... args) throws Exception {
        // 动态添加定时任务
        dynamicQuartzTask.start();

        // 20 秒后停止定时任务
        TimeUnit.SECONDS.sleep(20);
        dynamicQuartzTask.stop();

        // 5 秒后重新启动定时任务
        TimeUnit.SECONDS.sleep(5);
        dynamicQuartzTask.start();

        // 20 秒后停止定时任务
        TimeUnit.SECONDS.sleep(20);
        dynamicQuartzTask.stop();

        // 关闭 scheduler
        scheduler.shutdown();
    }
}

在上述代码中,我们定义了 ScheduleTaskTest 类,实现了 CommandLineRunner 接口,重写了 run 方法,该方法会先启动 DynamicQuartzTask 定时任务,20 秒后停止,再等待 5 秒后重新启动,最后再停止任务。

总结

在本篇攻略中,我们详细讲述了如何使用 Spring Boot 实现定时任务的动态增删启停,使用了 TaskScheduler 接口和 Quartz 框架两种方式,其中 Quartz 方式在实现动态性能方面更佳。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot如何实现定时任务的动态增删启停详解 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • 一篇文章带你了解Java 中序列化与反序列化

    一篇文章带你了解Java 中序列化与反序列化 引言 在Java编程中,可能需要将对象存储在文件中或通过网络传输。使用序列化来处理这些任务是很常见的方法。本篇文章将介绍Java中的序列化和反序列化的概念和用法,给你提供一个完整的攻略。 Serializable 接口 Java 中的序列化和反序列化要求被序列化的类必须实现 Serializable 接口。实现 …

    Java 2023年5月26日
    00
  • 为eclipse和IDEA配置tomcat服务器的方法

    为eclipse配置tomcat服务器: 下载安装tomcat服务器 在官网下载tomcat服务器压缩包,解压到本地目录即可(这里以Tomcat9为例): $ tar -zxvf apache-tomcat-9.0.50.tar.gz -C /usr/local 安装eclipse插件 打开eclipse,点击Help -> Eclipse Marke…

    Java 2023年5月19日
    00
  • Java十分钟精通类 封装 继承

    Java 十分钟精通类 封装 继承 Java 是面向对象编程语言,其中类、封装和继承是 OOP 的核心概念。在本文中,我们将介绍如何使用 Java 快速掌握这些概念。 类 在 Java 中,类是一种用于描述对象的结构。通过类定义,我们可以定义一个对象的属性和行为,从而为对象提供一个有意义的结构。Java 中的类定义如下: public class Class…

    Java 2023年5月26日
    00
  • Java MyBatis框架环境搭建详解

    Java MyBatis框架环境搭建详解 1. 环境要求 在开始搭建MyBatis框架之前,需要确保计算机已经安装以下软件: JDK(Java Development Kit)— 最好是JDK8及以上版本。 Eclipse(或者其他的Java IDE)— 推荐使用最新版本。 Maven(或者其他的构建工具)— 推荐使用最新版本。 MySQL(或者其他关系型数…

    Java 2023年6月2日
    00
  • 实例解析JSP中EL表达式的各种运用

    实例解析JSP中EL表达式的各种运用 在JSP页面中,EL表达式是非常常用的一种语法,用于简化代码的编写,提高代码的可读性。本文将详细讲解在JSP中EL表达式的各种运用。 EL表达式的基本语法 EL表达式用${}符号包裹,可以直接在JSP页面中使用。EL表达式的语法格式为${表达式},其中表达式可以是变量、运算符、方法调用等。 变量的使用 EL表达式可以用于…

    Java 2023年6月15日
    00
  • Java源码解析ArrayList及ConcurrentModificationException

    Java中的ArrayList是一个实现了List接口的动态数组,可以自动扩容。ArrayList提供了很多方便的方法,可以让我们对数组进行快速的操作。但是,在多线程环境下,操作ArrayList时容易抛出ConcurrentModificationException异常。下面是一个完整攻略,来详细讲解如何解析ArrayList和ConcurrentModi…

    Java 2023年5月26日
    00
  • Hibernate实现many-to-many的映射关系

    实现many-to-many映射关系的步骤一般如下: 创建数据库表格:many-to-many映射的本质是两个一对多关系,因此需要创建三张表:一个主要表,和两个从表。 定义实体类(Entity Class): 创建实体类,包含对应的类成员变量,其中需要注意的是,在类中要使用集合表示与其他实体类的关系。 建立映射关系:在实体类之间确定映射关系,通过注解实现 O…

    Java 2023年5月19日
    00
  • SpringBoot中 Jackson 日期的时区和日期格式问题解决

    下面是关于“SpringBoot中 Jackson 日期的时区和日期格式问题解决”的完整攻略。 问题描述 在SpringBoot的开发中,我们经常需要将Java对象转换为JSON格式的数据,而这种转换一般都是使用Jackson框架完成的。但是在转换日期类型的时候,会出现时区和日期格式的问题,比如: 默认情况下,Jackson框架将日期转换为UTC时区的ISO…

    Java 2023年5月20日
    00
合作推广
合作推广
分享本页
返回顶部