使用SpringBoot实现动态定时任务

一、引言

动态定时任务是指可以动态添加、修改、删除定时任务的功能,一般应用于需要灵活控制定时任务的业务场景。SpringBoot作为一个非常火热的Java框架,提供了非常便捷的定时任务的实现方式,本文主要介绍如何使用SpringBoot实现动态定时任务。下面我们将从多个方面进行详细的阐述。

二、定时任务的基本实现方式

SpringBoot中基于注解的定时任务实现方式非常便捷,只需在任务方法上添加注解@Scheduled即可实现简单的定时任务功能。例如,在SpringBoot应用程序中,执行某个方法,每隔一段时间输出某个信息,可以使用如下注解配置:

    @Scheduled(fixedRate = 5000)
    public void reportCurrentTime() {
        logger.info("当前时间是:{}", dateFormat.format(new Date()));
    }

上述代码中,@Scheduled注解指示该方法应该执行一个定时任务,fixedRate是一个参数,它规定任务每隔多少毫秒执行一次。在这种情况下,任务将每隔5秒查询一次数据库并记录当前时间。但是,这种方法只适合固定间隔的任务,如果想要控制任务的实现,就需要使用Cron表达式来定义定时策略。例如:

    @Scheduled(cron = "0 15 10 ? * *")
    public void scheduledTask() {
        // 执行任务
    }

上述代码中,@Scheduled注解中通过cron属性设置了一个Cron表达式,它表示任务将在每天的上午10点15分执行。

三、动态定时任务的实现方式

1. 存储定时任务信息

为了实现动态定时任务的功能,我们需要在数据库中存储定时任务的相关信息,如任务名称、任务描述、Cron表达式等。
我们可以建立一个定时任务数据表,将任务的相关信息存储在该表中。

CREATE TABLE `task_schedule` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '任务ID',
  `job_name` varchar(64) NOT NULL COMMENT '任务名称',
  `job_desc` varchar(256) DEFAULT NULL COMMENT '任务描述',
  `job_group` varchar(64) DEFAULT NULL COMMENT '任务所属分组',
  `job_cron` varchar(64) NOT NULL COMMENT 'Cron表达式',
  `job_status` int(2) NOT NULL COMMENT '任务状态,1:启用,0:禁用',
  `job_start_time` datetime DEFAULT NULL COMMENT '任务开始时间',
  `job_end_time` datetime DEFAULT NULL COMMENT '任务结束时间',
  `create_time` datetime NOT NULL COMMENT '任务创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '任务更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='动态任务调度表';

2. 使用Quartz实现动态定时任务

SpringBoot集成了Quartz,并且提供了官方的Quartz工具包starter,因此,我们可以基于Quartz实现动态定时任务。

2.1 添加依赖

首先我们需要添加Quartz相关的依赖和SpringBoot的依赖。

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

2.2 实现动态添加任务

SpringBoot提供了一个SchedulerFactoryBean来配置Quartz,我们可以通过SchedulerFactoryBean创建调度工厂,并使用任务调度工厂创建Scheduler调度器。下面我们来实现动态添加任务的代码。

/**
 * 任务调度核心类
 */
@Configuration
public class QuartzConfig {

    @Autowired
    private DataSource dataSource;

    /**
     * 配置SchedulerFactoryBean
     */
    @Bean
    public SchedulerFactoryBean schedulerFactoryBean() {
        SchedulerFactoryBean schedulerFactoryBean = new SchedulerFactoryBean();
        // 加载quartz数据源
        schedulerFactoryBean.setDataSource(dataSource);
        return schedulerFactoryBean;
    }

    /**
     * 创建Scheduler定时器
     */
    @Bean
    public Scheduler scheduler() throws SchedulerException {
        return schedulerFactoryBean().getScheduler();
    }

    /**
     * 添加任务
     * @param jobName 任务名称
     * @param jobGroup 任务分组
     * @param cronExpression Cron表达式
     * @param jobClass 任务类
     * @throws SchedulerException
     */
    public void addJob(String jobName, String jobGroup, String cronExpression, Class jobClass) throws SchedulerException {

        // 获取调度器
        Scheduler scheduler = scheduler();

        // 构建任务信息
        JobDetail jobDetail = JobBuilder.newJob(jobClass)
                .withIdentity(jobName, jobGroup)
                .build();

        // 设置任务触发器
        CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                .withIdentity(jobName, jobGroup)
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                .build();

        // 调度器中添加任务
        scheduler.scheduleJob(jobDetail, cronTrigger);

        // 启动调度器
        if(!scheduler.isShutdown()) {
            scheduler.start();
        }
    }

}

上述代码中,我们定义了一个SchedulerFactoryBean的Bean,并通过@Autowired注解将数据源注入到该Bean中。然后通过该Bean的方法getScheduler()获取到Scheduler调度器。
可以看到,我们通过Quartz提供的JobBuilder和TriggerBuilder创建JobDetail和CronTrigger决定了动态定时任务的任务执行和触发方式。最后调用调度器的方法scheduleJob()将任务添加到调度器中。

2.3 动态添加任务的调用

我们可以在任意位置调用添加任务方法addJob(),从而实现动态添加任务的功能。

    @Autowired
    private QuartzConfig quartzConfig;

    public boolean addTask(String jobName, String jobGroup, String cron, Class jobClass) {
        try {
            quartzConfig.addJob(jobName, jobGroup, cron, jobClass);
            return true;
        } catch (SchedulerException e) {
            // ...
            return false;
        }
    }

2.4 动态修改任务

动态修改任务需要调用Quartz的Scheduler修改任务,我们可以在上一步的代码中添加该功能。

    /**
     * 修改任务
     * @param jobName 任务名称
     * @param jobGroup 任务分组
     * @param cronExpression Cron表达式
     * @throws SchedulerException
     */
    public void modifyJob(String jobName, String jobGroup, String cronExpression) throws SchedulerException {

        // 获取调度器
        Scheduler scheduler = scheduler();

        // 根据任务名称和分组名称获取任务Key
        TriggerKey triggerKey = TriggerKey.triggerKey(jobName, jobGroup);

        // 根据任务Key获取Trigger
        CronTrigger cronTrigger = (CronTrigger) scheduler.getTrigger(triggerKey);

        // 重新设置Cron表达式
        CronScheduleBuilder builder = CronScheduleBuilder.cronSchedule(cronExpression);
        CronTrigger newTrigger = cronTrigger.getTriggerBuilder().withIdentity(triggerKey).withSchedule(builder).build();

        // 重置触发器中的Cron表达式
        scheduler.rescheduleJob(triggerKey, newTrigger);

    }

2.5 动态删除任务

在Quartz中删除任务需要调用Scheduler删除任务,Quartz提供了暂停、恢复和删除任务的方法,我们可以基于这些方法实现动态删除任务的功能。

    /**
     * 删除任务
     * @param jobName 任务名称
     * @param jobGroup 任务分组
     * @throws SchedulerException
     */
    public void deleteJob(String jobName, String jobGroup) throws SchedulerException {

        // 获取调度器
        Scheduler scheduler = scheduler();

        // 根据任务名称和分组名称获取任务Key
        JobKey jobKey = JobKey.jobKey(jobName, jobGroup);

        // 删除任务
        scheduler.deleteJob(jobKey);

    }

四、总结

本文详细介绍了如何使用SpringBoot实现动态定时任务功能,从定时任务的基本实现方式到动态定时任务的实现方式,逐步展示了动态定时任务的全过程,相信读完本文后,你已经掌握了使用SpringBoot实现动态定时任务的方法。

原创文章,作者:OXHMK,如若转载,请注明出处:https://www.506064.com/n/370018.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
OXHMKOXHMK
上一篇 2025-04-18 13:40
下一篇 2025-04-18 13:40

相关推荐

  • QML 动态加载实践

    探讨 QML 框架下动态加载实现的方法和技巧。 一、实现动态加载的方法 QML 支持从 JavaScript 中动态指定需要加载的 QML 组件,并放置到运行时指定的位置。这种技术…

    编程 2025-04-29
  • Java任务下发回滚系统的设计与实现

    本文将介绍一个Java任务下发回滚系统的设计与实现。该系统可以用于执行复杂的任务,包括可回滚的任务,及时恢复任务失败前的状态。系统使用Java语言进行开发,可以支持多种类型的任务。…

    编程 2025-04-29
  • Python爱心代码动态

    本文将从多个方面详细阐述Python爱心代码动态,包括实现基本原理、应用场景、代码示例等。 一、实现基本原理 Python爱心代码动态使用turtle模块实现。在绘制一个心形的基础…

    编程 2025-04-29
  • 从ga角度解读springboot

    springboot作为目前广受欢迎的Java开发框架,其中的ga机制在整个开发过程中起着至关重要的作用。 一、ga是什么 ga即Group Artifacts的缩写,它是Mave…

    编程 2025-04-29
  • Saturn 定时任务用法介绍

    本文将从以下几个方面对Saturn定时任务进行详细的阐述: 一、Saturn 定时任务简介 Saturn是一个分布式任务调度系统,支持在线添加、修改定时任务,支持多种任务类型,如J…

    编程 2025-04-29
  • t3.js:一个全能的JavaScript动态文本替换工具

    t3.js是一个非常流行的JavaScript动态文本替换工具,它是一个轻量级库,能够很容易地实现文本内容的递增、递减、替换、切换以及其他各种操作。在本文中,我们将从多个方面探讨t…

    编程 2025-04-28
  • 使用easypoi创建多个动态表头

    本文将详细介绍如何使用easypoi创建多个动态表头,让表格更加灵活和具有可读性。 一、创建单个动态表头 easypoi是一个基于POI操作Excel的Java框架,支持通过注解的…

    编程 2025-04-28
  • Python动态输入: 从基础使用到应用实例

    Python是一种高级编程语言,因其简单易学和可读性而备受欢迎。Python允许程序员通过标准输入或命令行获得用户输入,这使得Python语言无法预测或控制输入。在本文中,我们将详…

    编程 2025-04-28
  • 如何在dolphinscheduler中运行chunjun任务实例

    本文将从多个方面对dolphinscheduler运行chunjun任务实例进行详细的阐述,包括准备工作、chunjun任务配置、运行结果等方面。 一、准备工作 在运行chunju…

    编程 2025-04-28
  • SpringBoot Get方式请求传参用法介绍

    本文将从以下多个方面对SpringBoot Get方式请求传参做详细的阐述,包括URL传参、路径传参、请求头传参、请求体传参等,帮助读者更加深入地了解Get请求方式下传参的相关知识…

    编程 2025-04-27

发表回复

登录后才能评论