Spring 的任务调度机制概述
Spring 框架提供了强大的任务调度功能,主要有两种方式来实现任务调度:基于注解和基于 XML 配置。
1. 基于注解的任务调度
Spring 提供了 @Scheduled
注解,允许你方便地在方法上指定任务的执行时间。使用这种方式,需要在配置类上添加 @EnableScheduling
注解来启用调度功能。
下面是一个简单的示例:
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@Component
public class ScheduledTasks {
// 固定延迟,任务执行完成后等待 5 秒再执行下一次
@Scheduled(fixedDelay = 5000)
public void performTaskWithFixedDelay() {
System.out.println("Task executed with fixed delay at " + System.currentTimeMillis());
}
// 固定速率,每隔 3 秒执行一次任务
@Scheduled(fixedRate = 3000)
public void performTaskWithFixedRate() {
System.out.println("Task executed with fixed rate at " + System.currentTimeMillis());
}
// 使用 Cron 表达式,每天凌晨 2 点执行任务
@Scheduled(cron = "0 0 2 * * ?")
public void performTaskWithCron() {
System.out.println("Task executed with cron expression at " + System.currentTimeMillis());
}
}
配置类:
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
@Configuration
@EnableScheduling
public class AppConfig {
// 配置类可以添加其他配置
}
2. 基于 XML 配置的任务调度
在 Spring 中,也可以通过 XML 配置来实现任务调度。以下是一个简单的 XML 配置示例:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd">
<task:annotation-driven/>
<bean id="scheduledTasks" class="com.example.ScheduledTasks"/>
<task:scheduler id="taskScheduler" pool-size="10"/>
<task:scheduled-tasks scheduler="taskScheduler">
<task:scheduled ref="scheduledTasks" method="performTaskWithFixedRate" fixed-rate="3000"/>
</task:scheduled-tasks>
</beans>
实现动态任务调度
动态任务调度意味着可以在运行时添加、修改或删除任务。Spring 提供了 ThreadPoolTaskScheduler
类来实现动态任务调度。
以下是一个实现动态任务调度的示例:
DynamicTaskSchedulerExample.java
import org.springframework.scheduling.TaskScheduler;
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.concurrent.ScheduledFuture;
@Component
@EnableScheduling
public class DynamicTaskSchedulerExample implements SchedulingConfigurer {
private TaskScheduler taskScheduler;
private ScheduledFuture<?> scheduledFuture;
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskScheduler = taskRegistrar.getScheduler();
}
public void startTask(String cronExpression) {
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
}
scheduledFuture = taskScheduler.schedule(() -> {
System.out.println("Dynamic task executed at " + System.currentTimeMillis());
}, new CronTrigger(cronExpression));
}
public void stopTask() {
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
}
}
}
代码解释
DynamicTaskSchedulerExample
类实现了SchedulingConfigurer
接口,重写了configureTasks
方法,获取TaskScheduler
实例。startTask
方法用于启动一个新的任务,可以传入 Cron 表达式来指定任务的执行时间。如果之前已经有任务在运行,会先取消之前的任务。stopTask
方法用于停止当前正在运行的任务。
你可以在其他类中注入 DynamicTaskSchedulerExample
类,并调用 startTask
和 stopTask
方法来动态管理任务调度。例如:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class TaskController {
@Autowired
private DynamicTaskSchedulerExample dynamicTaskScheduler;
@GetMapping("/startTask")
public String startTask(@RequestParam String cronExpression) {
dynamicTaskScheduler.startTask(cronExpression);
return "Task started with cron expression: " + cronExpression;
}
@GetMapping("/stopTask")
public String stopTask() {
dynamicTaskScheduler.stopTask();
return "Task stopped";
}
}
通过上述代码,你可以在运行时动态地启动和停止任务,并且可以根据需要修改任务的执行时间。