动态添加定时任务:Java前端与后端的完美配合

在现代软件开发中,定时任务是一项常见而重要的需求。通过定时任务,我们能够在后台定期执行某些操作,比如清理过期数据、推送通知等。这篇文章将重点介绍如何在Java后端中动态添加定时任务,并结合前端传递的时间表达式来实现这一功能。

1. 项目需求

假设我们在开发一个任务管理系统,用户能够通过前端界面设置定时任务并指定执行时间。后端接受前端发送的时间表达式后,动态添加任务并按期执行。

2. 技术栈

  • 前端:JavaScript(使用框架如Vue、React等)
  • 后端:Java(Spring Boot)
  • 定时任务调度:Quartz

3. 系统架构

整个系统可以分为以下几个模块:

  • 前端模块:用户输入时间表达式,提交至后端。
  • 后端模块:接收时间表达式,解析并动态添加Quartz定时任务。
  • 任务执行模块:根据设定的时间定时执行任务。

以下是系统的类图:

classDiagram
    class Frontend {
        +submitSchedule(timeExpression: String)
    }
    class Backend {
        +receiveSchedule(timeExpression: String)
        +createSchedulerJob(timeExpression: String)
    }
    class QuartzScheduler {
        +scheduleJob(job: JobDetail, trigger: Trigger)
    }
    class Task {
        +execute()
    }

    Frontend --> Backend
    Backend --> QuartzScheduler
    QuartzScheduler --> Task

4. 前端代码示例

前端使用JavaScript来提交时间表达式。这里用Vue.js做示例:

<template>
  <div>
      <h2>定时任务设置</h2>
      <input type="text" v-model="expression" placeholder="如:0/5 * * * * ? 表示每5秒执行一次"/>
      <button @click="submitSchedule">添加定时任务</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      expression: ''
    }
  },
  methods: {
    async submitSchedule() {
      try {
        await fetch('/api/schedule', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({ timeExpression: this.expression })
        });
        alert('定时任务已添加');
      } catch (error) {
        console.error('添加定时任务失败:', error);
      }
    }
  }
}
</script>

以上代码实现了一个简单的前端界面,用户可以在输入框输入时间表达式,然后点击提交按钮将其发送至后端。

5. 后端代码实现

接下来我们看后端的实现。使用Spring Boot和Quartz来实现定时任务的动态添加。

5.1 添加依赖

首先,确保在pom.xml中添加所需的Quartz依赖:

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

5.2 后端Controller

然后,在后端创建一个控制器类来接收前端传来的时间表达式:

import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class ScheduleController {

    @Autowired
    private Scheduler scheduler;

    @PostMapping("/schedule")
    public String receiveSchedule(@RequestBody ScheduleRequest request) {
        createSchedulerJob(request.getTimeExpression());
        return "定时任务已创建";
    }

    private void createSchedulerJob(String cronExpression) {
        JobDetail jobDetail = JobBuilder.newJob(Task.class)
                .withIdentity("dynamicJob", "group1")
                .build();

        Trigger trigger = TriggerBuilder.newTrigger()
                .withIdentity("dynamicTrigger", "group1")
                .withSchedule(CronScheduleBuilder.cronSchedule(cronExpression))
                .build();

        try {
            scheduler.scheduleJob(jobDetail, trigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
        }
    }
}

5.3 调度任务类

接着,我们需要定义一个简单的任务类,所有需要定时执行的操作都放在这里:

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class Task implements Job {
    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        System.out.println("任务执行时间: " + System.currentTimeMillis());
    }
}

5.4 请求对象

为了接收前端请求体中的数据,定义一个请求对象:

public class ScheduleRequest {
    private String timeExpression;

    public String getTimeExpression() {
        return timeExpression;
    }

    public void setTimeExpression(String timeExpression) {
        this.timeExpression = timeExpression;
    }
}

6. 总结

本篇文章演示了如何通过前端输入时间表达式,后端动态添加定时任务。在整个流程中,我们利用Spring Boot与Quartz结合,实现一个简单的定时任务管理系统。

小结

  • 前端通过RESTful API将时间表达式发送给后端。
  • 后端解析时间表达式,并使用Quartz定时任务调度向任务调度器注册。
  • 当时间条件满足时,系统自动执行相应的任务。

通过这样的方法,我们可以根据业务需要灵活地添加、管理定时任务,提高系统的可扩展性和灵活性。希望这篇文章能够帮助到在定时任务管理方面的开发者!