@Scheduled定时任务动态数据库配置开启关闭

建表

CREATE TABLE `task_config` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `task_name` varchar(255) DEFAULT NULL COMMENT '定时任务名称',
  `cron_expression` varchar(255) DEFAULT NULL COMMENT 'cron表达式  6位,不指定年份,到周结束',
  `task_enabled` tinyint(1) DEFAULT NULL COMMENT '0false关闭/1true开启',
  `describe` varchar(255) DEFAULT NULL COMMENT '描述',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;

后端代码

package com.jsh.erp.schedule;

import com.jsh.erp.controller.ExternalController;
import com.jsh.erp.datasource.entities.TaskJob;
import com.jsh.erp.datasource.mappers.TaskJobMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.ScheduledFuture;

/**
 * 数据同步
 */
@Component
@EnableScheduling
public class DataSyncTask {

    private Logger logger = LoggerFactory.getLogger(DataSyncTask.class);

    @Autowired
    private ExternalController externalController;

    @Autowired
    private TaskJobMapper taskJobMapper;

    private static final String TASK_NAME = "DataSyncTask";

    //cron表达式
    public String cronExpression = "30 30 21 * * *";

    //定时任务开启关闭
    public boolean taskEnabled = false;

    private ScheduledFuture<?> scheduledFuture;

    @Autowired
    private TaskScheduler taskScheduler;

    @Bean
    public TaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10); // 可以根据需要调整线程池大小
        scheduler.setThreadNamePrefix("scheduled-task-");
        return scheduler;
    }

    @PostConstruct
    public void init() {
        loadTaskConfig();
    }

    // 从数据库中加载定时任务配置
    private void loadTaskConfig() {
        TaskJob config = taskJobMapper.getTaskMessage(TASK_NAME);
        if (config != null) {
            this.cronExpression = config.getCronExpression();
            this.taskEnabled = config.isTaskEnabled();
        }
    }

    // 定时读取数据库,检查配置的变化
    @Scheduled(cron = "0 0/5 * * * ?")  // 每 5 分钟检查一次数据库中的配置
    public void checkTaskConfig() {
        TaskJob config = taskJobMapper.getTaskMessage(TASK_NAME);
        if (config != null) {
            if (this.taskEnabled != config.isTaskEnabled() || !this.cronExpression.equals(config.getCronExpression())) {
                this.cronExpression = config.getCronExpression();
                this.taskEnabled = config.isTaskEnabled();
                restartTask();
            }
        }
    }

    private void startScheduledTask() {
        if (taskEnabled) {
            scheduledFuture = taskScheduler.schedule(this::syncData, new CronTrigger(cronExpression));
            logger.info(TASK_NAME + "定时任务开启,cron: " + cronExpression);
        }
    }

    private void restartTask() {
        if (scheduledFuture != null) {
            scheduledFuture.cancel(false);
        }
        startScheduledTask();
    }

    @Scheduled(cron = "#{dataSyncTask.cronExpression}")
    public void syncData() {
        logger.info("进入同步定时...");
        if (taskEnabled) {
            logger.info("开始...数据同步数据");
            externalController.insertAllData();
            logger.info("结束....数据同步");
        }
    }
}
posted @ 2025-06-16 11:34  小侯学编程  阅读(57)  评论(0)    收藏  举报