import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
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.scheduling.concurrent.ThreadPoolTaskScheduler;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Configuration
@EnableScheduling
public class DynamicSchedulingConfig implements SchedulingConfigurer {
@Autowired
private ScheduledTaskConfigRepository taskConfigRepository;
private final Map<Long, Runnable> scheduledTasks = new ConcurrentHashMap<>();
private final ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskScheduler.initialize();
// 定时刷新任务配置
taskRegistrar.addFixedDelayTask(this::refreshTasks, 5000);
// 添加默认的定时任务(示例)
taskRegistrar.addTriggerTask(
() -> System.out.println("默认的定时任务执行了!"),
triggerContext -> new CronTrigger("0/10 * * * * ?").nextExecutionTime(triggerContext)
);
}
private void refreshTasks() {
System.out.println("刷新任务配置...");
// 获取最新的任务配置
Iterable<ScheduledTaskConfig> taskConfigs = taskConfigRepository.findAll();
// 根据数据库中的配置更新任务
updateScheduledTasks(taskConfigs);
}
private void updateScheduledTasks(Iterable<ScheduledTaskConfig> taskConfigs) {
// 遍历数据库中的配置
for (ScheduledTaskConfig taskConfig : taskConfigs) {
Long taskId = taskConfig.getId();
// 如果任务已经注册,但是 Cron 表达式发生了变化,取消旧任务并重新注册
if (scheduledTasks.containsKey(taskId) && !scheduledTasks.get(taskId).equals(taskConfig.getCronExpression())) {
cancelTask(taskId);
}
// 如果任务未注册,注册新任务
if (!scheduledTasks.containsKey(taskId)) {
registerTask(taskConfig);
}
}
// 如果数据库中的任务被删除,取消已注册的任务
for (Long taskId : scheduledTasks.keySet()) {
if (StreamSupport.stream(taskConfigs.spliterator(), false)
.noneMatch(config -> config.getId().equals(taskId))) {
cancelTask(taskId);
}
}
}
private void registerTask(ScheduledTaskConfig taskConfig) {
Long taskId = taskConfig.getId();
Runnable task = () -> executeTaskLogic(taskConfig);
scheduledTasks.put(taskId, task);
// 使用 ThreadPoolTaskScheduler 执行定时任务
taskScheduler.schedule(task, new CronTrigger(taskConfig.getCronExpression()));
}
private void cancelTask(Long taskId) {
Runnable task = scheduledTasks.remove(taskId);
taskScheduler.getScheduledThreadPoolExecutor().remove(task);
}
private void executeTaskLogic(ScheduledTaskConfig taskConfig) {
System.out.println("定时任务[" + taskConfig.getTaskName() + "]执行了!");
}
}