欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Springboot實(shí)現(xiàn)動態(tài)定時任務(wù)管理的示例代碼

 更新時間:2023年07月07日 10:39:17   作者:星空流年  
最近在做spring boot項(xiàng)目開發(fā)中,由于使用@EnableScheduling注解和@Scheduled注解來實(shí)現(xiàn)的定時任務(wù),只能靜態(tài)的創(chuàng)建定時任務(wù),不能動態(tài)修改、添加、刪除、啟/停任務(wù),下面通過本文給大家介紹Springboot實(shí)現(xiàn)動態(tài)定時任務(wù)管理的方法,感興趣的朋友跟隨小編一起看看吧

最近在做spring boot項(xiàng)目開發(fā)中,由于使用@EnableScheduling注解和@Scheduled注解來實(shí)現(xiàn)的定時任務(wù),只能靜態(tài)的創(chuàng)建定時任務(wù),不能動態(tài)修改、添加、刪除、啟/停任務(wù)。由于項(xiàng)目開發(fā)體量不大,如果引入xxl-job等開源框架處理,會導(dǎo)致項(xiàng)目過于臃腫和復(fù)雜,同時通過查找相關(guān)資料,發(fā)現(xiàn)可以通過改造spring-context.jar包中org.springframework.scheduling.ScheduledTaskRegistrar類實(shí)現(xiàn)動態(tài)增刪啟停定時任務(wù)功能,而且網(wǎng)上也有類似文章介紹,于是便動手實(shí)踐了一下,發(fā)現(xiàn)是可行的。

1、定時任務(wù)表設(shè)計(jì)

CREATE TABLE IF NOT EXISTS `schedule_setting` (
  `job_id` int NOT NULL AUTO_INCREMENT COMMENT '任務(wù)ID',
  `bean_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'bean名稱',
  `method_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '方法名稱',
  `method_params` varchar(8192) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '方法參數(shù)',
  `cron_expression` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT 'cron表達(dá)式',
  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '備注',
  `job_status` tinyint(1) DEFAULT NULL COMMENT '狀態(tài)(1為啟用,0為停用)',
  `create_time` datetime DEFAULT NULL COMMENT '創(chuàng)建時間',
  `update_time` datetime DEFAULT NULL COMMENT '修改時間',
  PRIMARY KEY (`job_id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

2、定時任務(wù)實(shí)體類及對應(yīng)Mapper

關(guān)于定時任務(wù)實(shí)體類一些基本的增刪改查接口代碼,這里為了簡便操作,引入了mybatis-plus中的ActiveRecord 模式,通過實(shí)體類繼承Model類實(shí)現(xiàn),關(guān)于Model類的說明,參看如下文檔:https://baomidou.com/pages/49cc81/#activerecord-%E6%A8%A1%E5%BC%8F

2.1、定時任務(wù)實(shí)體類

<strong>import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
 * 定時任務(wù)實(shí)體類
 *
 * @author 星空流年
 * @date 2023/7/5
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class ScheduleSetting extends Model<ScheduleSetting> {
    /**
     * 任務(wù)ID
     */
    @TableId(type = IdType.AUTO)
    private Integer jobId;
    /**
     * bean名稱
     */
    private String beanName;
    /**
     * 方法名稱
     */
    private String methodName;
    /**
     * 方法參數(shù)
     */
    private String methodParams;
    /**
     * cron表達(dá)式
     */
    private String cronExpression;
    /**
     * 狀態(tài)(1為啟用, 0為停用)
     */
    private Integer jobStatus;
    /**
     * 備注
     */
    private String remark;
    /**
     * 創(chuàng)建時間
     */
    private Date createTime;
    /**
     * 更新時間
     */
    private Date updateTime;
}</strong>

2.2、定時任務(wù)狀態(tài)枚舉類

<strong>/**
 * 定時任務(wù)啟用、停用枚舉類
 *
 * @author 星空流年
 * @date 2023/7/5
 */
public enum ScheduleJobEnum {
    /**
     * 啟用
     */
    ENABLED(1),
    /**
     * 停用
     */
    DISABLED(0);
    private final int statusCode;
    ScheduleJobEnum(int code) {
        this.statusCode = code;
    }
    public int getStatusCode() {
        return statusCode;
    }
}</strong>

2.3、定時任務(wù)Mapper類

<strong>import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import xxx.entity.ScheduleSetting;
import org.apache.ibatis.annotations.Mapper;
/**
 * ScheduleSetting表數(shù)據(jù)庫訪問層
 *
 * @author 星空流年
 * @date 2023/7/5
 */
@Mapper
@SuppressWarnings("all")
public interface ScheduleSettingMapper extends BaseMapper<ScheduleSetting> {
}</strong>

3、定時任務(wù)線程池相關(guān)類

3.1、定時任務(wù)線程池配置類

<strong>import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
/**
 * 執(zhí)行定時任務(wù)的線程池配置類
 *
 * @author 星空流年
 * @date 2023/7/5
 */
@Configuration
public class SchedulingConfig {
    @Bean
    public TaskScheduler taskScheduler() {
        // 獲取系統(tǒng)處理器個數(shù), 作為線程池?cái)?shù)量
        int corePoolSize = Runtime.getRuntime().availableProcessors();
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        // 定時任務(wù)執(zhí)行線程池核心線程數(shù)
        taskScheduler.setPoolSize(corePoolSize);
        taskScheduler.setRemoveOnCancelPolicy(true);
        taskScheduler.setThreadNamePrefix("TaskSchedulerThreadPool-");
        return taskScheduler;
    }
}</strong>

3.2、獲取Bean工具類

<strong>import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
 * 獲取Spring中Bean工具類
 *
 * @author 星空流年
 * @date 2023/7/5
 */
@Component
@SuppressWarnings("all")
public class SpringContextUtils implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtils.applicationContext = applicationContext;
    }
    public static Object getBean(String name) {
        return applicationContext.getBean(name);
    }
    public static <T> T getBean(Class<T> requiredType) {
        return applicationContext.getBean(requiredType);
    }
    public static <T> T getBean(String name, Class<T> requiredType) {
        return applicationContext.getBean(name, requiredType);
    }
    public static boolean containsBean(String name) {
        return applicationContext.containsBean(name);
    }
    public static boolean isSingleton(String name) {
        return applicationContext.isSingleton(name);
    }
    public static Class<? extends Object> getType(String name) {
        return applicationContext.getType(name);
    }
}</strong>

3.3、Runnable接口實(shí)現(xiàn)類

<strong>import lombok.extern.slf4j.Slf4j;
import xxx.util.SpringContextUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Method;
import java.util.Objects;
/**
 * Runnable接口實(shí)現(xiàn)類
 * 被定時任務(wù)線程池調(diào)用, 用來執(zhí)行指定bean里面的方法
 *
 * @author 星空流年
 * @date 2023/7/5
 */
@Slf4j
@SuppressWarnings("all")
public class SchedulingRunnable implements Runnable {
    private final String beanName;
    private final String methodName;
    private final String params;
    private final Integer jobId;
    public SchedulingRunnable(String beanName, String methodName, String params, Integer jobId) {
        this.beanName = beanName;
        this.methodName = methodName;
        this.params = params;
        this.jobId = jobId;
    }
    @Override
    public void run() {
        log.info("定時任務(wù)開始執(zhí)行 - bean: {}, 方法: {}, 參數(shù): {}, 任務(wù)ID: {}", beanName, methodName, params, jobId);
        long startTime = System.currentTimeMillis();
        try {
            Object target = SpringContextUtils.getBean(beanName);
            Method method;
            if (StringUtils.isNotEmpty(params)) {
                method = target.getClass().getDeclaredMethod(methodName, String.class);
            } else {
                method = target.getClass().getDeclaredMethod(methodName);
            }
            ReflectionUtils.makeAccessible(method);
            if (StringUtils.isNotEmpty(params)) {
                method.invoke(target, params);
            } else {
                method.invoke(target);
            }
        } catch (Exception ex) {
            log.error("定時任務(wù)執(zhí)行異常 - bean: {}, 方法: {}, 參數(shù): {}, 任務(wù)ID: {}", beanName, methodName, params, jobId, ex);
        }
        long times = System.currentTimeMillis() - startTime;
        log.info("定時任務(wù)執(zhí)行結(jié)束 - bean: {}, 方法: {}, 參數(shù): {}, 任務(wù)ID: {}, 耗時: {}毫秒", beanName, methodName, params, jobId, times);
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (Objects.isNull(obj) || getClass() != obj.getClass()) {
            return false;
        }
        SchedulingRunnable that = (SchedulingRunnable) obj;
        if (Objects.isNull(params)) {
            return beanName.equals(that.beanName) &&
                    methodName.equals(that.methodName) &&
                    that.params == null;
        }
        return beanName.equals(that.beanName) &&
                methodName.equals(that.methodName) &&
                params.equals(that.params) &&
                jobId.equals(that.jobId);
    }
    @Override
    public int hashCode() {
        if (Objects.isNull(params)) {
            return Objects.hash(beanName, methodName, jobId);
        }
        return Objects.hash(beanName, methodName, params, jobId);
    }
}</strong>

3.4、ScheduledFuture包裝類

<strong>import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
/**
 * 定時任務(wù)包裝類
 * <p>
 * ScheduledFuture是ScheduledExecutorService定時任務(wù)線程池的執(zhí)行結(jié)果
 * </p>
 *
 * @author 星空流年
 * @date 2023/7/5
 */
@SuppressWarnings("all")
public final class ScheduledTask {
    volatile ScheduledFuture<?> future;
    /**
     * 取消定時任務(wù)
     */
    public void cancel() {
        ScheduledFuture<?> scheduledFuture = this.future;
        if (Objects.nonNull(scheduledFuture)) {
            scheduledFuture.cancel(true);
        }
    }
}</strong>

3.5、定時任務(wù)注冊類

<strong>import javax.annotation.Resource;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.config.CronTask;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 定時任務(wù)注冊類
 * <p>
 * 定時任務(wù)注冊類, 主要用于增加、刪除定時任務(wù)
 * </p>
 * 
 * @author 星空流年
 * @date 2023/7/5
 */
@Component
@SuppressWarnings("all")
public class CronTaskRegistrar implements DisposableBean {
    private final Map<Runnable, ScheduledTask> scheduledTasks = new ConcurrentHashMap<>(16);
    @Resource
    private TaskScheduler taskScheduler;
    public void addCronTask(Runnable task, String cronExpression) {
        addCronTask(new CronTask(task, cronExpression));
    }
    public void addCronTask(CronTask cronTask) {
        if (Objects.nonNull(cronTask)) {
            Runnable task = cronTask.getRunnable();
            if (this.scheduledTasks.containsKey(task)) {
                removeCronTask(task);
            }
            this.scheduledTasks.put(task, scheduleCronTask(cronTask));
        }
    }
    public void removeCronTask(Runnable task) {
        ScheduledTask scheduledTask = this.scheduledTasks.remove(task);
        if (Objects.nonNull(scheduledTask)) {
            scheduledTask.cancel();
        }
    }
    public ScheduledTask scheduleCronTask(CronTask cronTask) {
        ScheduledTask scheduledTask = new ScheduledTask();
        scheduledTask.future = this.taskScheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
        return scheduledTask;
    }
    @Override
    public void destroy() {
        this.scheduledTasks.values().forEach(ScheduledTask::cancel);
        this.scheduledTasks.clear();
    }
}</strong>

4、定時任務(wù)增刪改工具類

<strong>import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import javax.annotation.Resource;
import net.cnki.nxgp.metric.recording.rule.entity.pojo.ScheduleJobEnum;
import net.cnki.nxgp.metric.recording.rule.task.component.CronTaskRegistrar;
import net.cnki.nxgp.metric.recording.rule.task.component.SchedulingRunnable;
import net.cnki.nxgp.metric.recording.rule.task.entity.ScheduleSetting;
import org.springframework.stereotype.Component;
import java.util.Date;
/**
 * 定時任務(wù)動態(tài)管理具體實(shí)現(xiàn)工具類
 *
 * @author 星空流年
 * @date 2023/7/5
 */
@Component
public class TaskUtils {
    @Resource
    private CronTaskRegistrar cronTaskRegistrar;
    /**
     * 添加定時任務(wù)
     *
     * @param scheduleJob 定時任務(wù)實(shí)體類
     * @return boolean
     */
    public ScheduleSetting insertTaskJob(ScheduleSetting scheduleJob) {
        scheduleJob.setCreateTime(new Date());
        scheduleJob.setUpdateTime(new Date());
        boolean insert = scheduleJob.insert();
        if (!insert) {
            return null;
        }
        // 添加成功, 并且狀態(tài)是啟用, 則直接放入任務(wù)器
        if (scheduleJob.getJobStatus().equals(ScheduleJobEnum.ENABLED.getStatusCode())) {
            SchedulingRunnable task = new SchedulingRunnable(scheduleJob.getBeanName(), scheduleJob.getMethodName(), scheduleJob.getMethodParams(), scheduleJob.getJobId());
            cronTaskRegistrar.addCronTask(task, scheduleJob.getCronExpression());
        }
        return scheduleJob;
    }
    /**
     * 更新定時任務(wù)
     *
     * @param scheduleJob 定時任務(wù)實(shí)體類
     * @return boolean
     */
    public boolean updateTaskJob(ScheduleSetting scheduleJob) {
        scheduleJob.setCreateTime(new Date());
        scheduleJob.setUpdateTime(new Date());
        // 查詢修改前任務(wù)
        ScheduleSetting existedSysJob = new ScheduleSetting();
        LambdaQueryWrapper<ScheduleSetting> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ScheduleSetting::getJobId, scheduleJob.getJobId());
        existedSysJob = existedSysJob.selectOne(queryWrapper);
        // 修改任務(wù)
        LambdaUpdateWrapper<ScheduleSetting> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ScheduleSetting::getJobId, scheduleJob.getJobId());
        boolean update = scheduleJob.update(updateWrapper);
        if (!update) {
            return false;
        }
        // 修改成功, 則先刪除任務(wù)器中的任務(wù), 并重新添加
        SchedulingRunnable preTask = new SchedulingRunnable(existedSysJob.getBeanName(), existedSysJob.getMethodName(), existedSysJob.getMethodParams(), existedSysJob.getJobId());
        cronTaskRegistrar.removeCronTask(preTask);
        // 如果修改后的任務(wù)狀態(tài)是啟用, 就加入任務(wù)器
        if (scheduleJob.getJobStatus().equals(ScheduleJobEnum.ENABLED.getStatusCode())) {
            SchedulingRunnable task = new SchedulingRunnable(scheduleJob.getBeanName(), scheduleJob.getMethodName(), scheduleJob.getMethodParams(), scheduleJob.getJobId());
            cronTaskRegistrar.addCronTask(task, scheduleJob.getCronExpression());
        }
        return true;
    }
    /**
     * 刪除定時任務(wù)
     *
     * @param jobId 定時任務(wù)id
     * @return boolean
     */
    public boolean deleteTaskJob(Integer jobId) {
        // 先查詢要刪除的任務(wù)信息
        ScheduleSetting existedJob = new ScheduleSetting();
        LambdaQueryWrapper<ScheduleSetting> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ScheduleSetting::getJobId, jobId);
        existedJob = existedJob.selectOne(queryWrapper);
        // 刪除
        boolean delete = existedJob.delete(queryWrapper);
        if (!delete) {
            return false;
        }
        // 刪除成功, 并刪除定時任務(wù)器中的對應(yīng)任務(wù)
        SchedulingRunnable task = new SchedulingRunnable(existedJob.getBeanName(), existedJob.getMethodName(), existedJob.getMethodParams(), jobId);
        cronTaskRegistrar.removeCronTask(task);
        return true;
    }
    /**
     * 停止/啟動定時任務(wù)
     *
     * @param jobId     定時任務(wù)id
     * @param jobStatus 定時任務(wù)狀態(tài)
     * @return boolean
     */
    public boolean changeStatus(Integer jobId, Integer jobStatus) {
        // 修改任務(wù)狀態(tài)
        ScheduleSetting scheduleSetting = new ScheduleSetting();
        scheduleSetting.setJobStatus(jobStatus);
        boolean update = scheduleSetting.update(new LambdaUpdateWrapper<ScheduleSetting>().eq(ScheduleSetting::getJobId, jobId));
        if (!update) {
            return false;
        }
        // 查詢修改后的任務(wù)信息
        ScheduleSetting existedJob = new ScheduleSetting();
        existedJob = existedJob.selectOne(new LambdaQueryWrapper<ScheduleSetting>().eq(ScheduleSetting::getJobId, jobId));
        // 如果狀態(tài)是啟用, 則添加任務(wù)
        SchedulingRunnable task = new SchedulingRunnable(existedJob.getBeanName(), existedJob.getMethodName(), existedJob.getMethodParams(), jobId);
        if (existedJob.getJobStatus().equals(ScheduleJobEnum.ENABLED.getStatusCode())) {
            cronTaskRegistrar.addCronTask(task, existedJob.getCronExpression());
        } else {
            // 反之, 則刪除任務(wù)
            cronTaskRegistrar.removeCronTask(task);
        }
        return true;
    }
}</strong>

5、定時任務(wù)執(zhí)行類

<strong>import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
/**
 * 定時任務(wù)類
 *
 * @author 星空流年
 * @date 2023/7/5
 */
@Slf4j
@Component("jobTaskTest")
public class JobTask {
    /**
     * 此處為需要執(zhí)行定時任務(wù)的方法, 可以根據(jù)需求自行添加對應(yīng)的定時任務(wù)方法
     */
    public void upsertTask(String params) {
        // ...
        log.info("定時任務(wù)執(zhí)行啦...");
    }
}</strong>

6、定時任務(wù)測試類

<strong>import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class ScheduleJobApplicationTests {
    @Resource
    private TaskUtils taskUtils;
    @Test
    public void testInsertTask() {
        ScheduleSetting scheduleJob = new ScheduleSetting();
        // 此處beanName, methodName對應(yīng)定時任務(wù)執(zhí)行類中定義的beanName、方法名
        scheduleJob.setBeanName("jobTaskTest");
        scheduleJob.setMethodName("upsertTask");
        // 方法參數(shù)由于定時任務(wù)Runnable接口包裝類中定義為字符串類型, 如果為其他類型,注意轉(zhuǎn)換
        scheduleJob.setMethodParams("params");
        scheduleJob.setJobStatus(ScheduleJobEnum.ENABLED.getStatusCode());
        String cron = "*/30 * * * * ?";
        scheduleJob.setCronExpression(cron);
        scheduleJob.setRemark("定時任務(wù)新增");
        ScheduleSetting scheduleTask = taskUtils.insertTaskJob(scheduleJob);
        if (Objects.isNull(scheduleTask)) {
            log.error("定時任務(wù)新增失敗");
        }
    }
    @Test
    public void testUpdateTask() {
        ScheduleSetting scheduleJob = new ScheduleSetting();
        scheduleJob.setJobId(1);
        // 此處beanName, methodName對應(yīng)定時任務(wù)執(zhí)行類中定義的beanName、方法名
        scheduleJob.setBeanName("jobTaskTest");
        scheduleJob.setMethodName("upsertTask");
        // 方法參數(shù)由于定時任務(wù)Runnable接口包裝類中定義為字符串類型, 如果為其他類型,注意轉(zhuǎn)換
        scheduleJob.setMethodParams("params");
        scheduleJob.setJobStatus(ScheduleJobEnum.ENABLED.getStatusCode());
        String cron = "*/60 * * * * ?";
        scheduleJob.setCronExpression(cron);
        scheduleJob.setRemark("定時任務(wù)更新");
        ScheduleSetting scheduleTask = taskUtils.updateTaskJob(scheduleJob);
        if (Objects.isNull(scheduleTask)) {
            log.error("定時任務(wù)更新失敗");
        }
    }
    @Test
    public void testChangeTaskStatus() {
        boolean changeFlag = taskUtils.changeStatus(1, 0);
        if (!changeFlag) {
            log.error("定時任務(wù)狀態(tài)更新失敗");
        }
    }
    @Test
    public void testDeleteTask() {
        boolean deleteFlag = taskUtils.deleteTaskJob(1);
        if (!deleteFlag) {
            log.error("定時任務(wù)刪除失敗");
        }
    }
}</strong>

7、初始化定時任務(wù)

<strong>import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import xxx.entity.pojo.ScheduleJobEnum;
import xxx.entity.ScheduleSetting;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.List;
/**
 * 初始化數(shù)據(jù)庫中啟用狀態(tài)下的定時任務(wù)
 *
 * @author 星空流年
 * @date 2023/7/5
 */
@Slf4j
@Component
public class TaskJobInitRunner implements CommandLineRunner {
    @Resource
    private CronTaskRegistrar cronTaskRegistrar;
    @Override
    public void run(String... args) {
        // 初始化加載數(shù)據(jù)庫中狀態(tài)為啟用的定時任務(wù)
        ScheduleSetting existedSysJob = new ScheduleSetting();
        List<ScheduleSetting> jobList = existedSysJob.selectList(new LambdaQueryWrapper<ScheduleSetting>().eq(ScheduleSetting::getJobStatus, ScheduleJobEnum.ENABLED.getStatusCode()));
        if (CollectionUtils.isNotEmpty(jobList)) {
            jobList.forEach(job -> {
                SchedulingRunnable task = new SchedulingRunnable(job.getBeanName(), job.getMethodName(), job.getMethodParams(), job.getJobId());
                cronTaskRegistrar.addCronTask(task, job.getCronExpression());
            });
            log.info("~~~~~~~~~~~~~~~~~~~~~ 定時任務(wù)初始化完成 ~~~~~~~~~~~~~~~~~~~~~");
        }
    }
}</strong>

到此這篇關(guān)于Springboot實(shí)現(xiàn)動態(tài)定時任務(wù)管理的文章就介紹到這了,更多相關(guān)Springboot動態(tài)定時任務(wù)管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 二叉搜索樹實(shí)例練習(xí)

    二叉搜索樹實(shí)例練習(xí)

    一棵二叉查找樹是按二叉樹結(jié)構(gòu)來組織的。這樣的樹可以用鏈表結(jié)構(gòu)表示,其中每一個結(jié)點(diǎn)都是一個對象
    2012-11-11
  • Java實(shí)現(xiàn)讀取項(xiàng)目中文件(.json或.properties)的方法詳解

    Java實(shí)現(xiàn)讀取項(xiàng)目中文件(.json或.properties)的方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)讀取項(xiàng)目中文件的方法,例如.json或.properties,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-04-04
  • 使用HttpClient調(diào)用接口的實(shí)例講解

    使用HttpClient調(diào)用接口的實(shí)例講解

    下面小編就為大家?guī)硪黄褂肏ttpClient調(diào)用接口的實(shí)例講解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • IDEA+Maven打JAR包的兩種方法步驟詳解

    IDEA+Maven打JAR包的兩種方法步驟詳解

    Idea中為一般的非Web項(xiàng)目打Jar包是有自己的方法的,下面這篇文章主要給大家介紹了關(guān)于IDEA+Maven打JAR包的兩種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • springboot命令行啟動的方法詳解

    springboot命令行啟動的方法詳解

    這篇文章主要介紹了springboot命令行啟動的方法,本文通過兩種方法給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • springboot之security?FilterSecurityInterceptor的使用要點(diǎn)記錄

    springboot之security?FilterSecurityInterceptor的使用要點(diǎn)記錄

    這篇文章主要介紹了springboot之security?FilterSecurityInterceptor的使用要點(diǎn)記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • springboot跨域過濾器fetch react Response to preflight request doesn‘t pass access control check問題

    springboot跨域過濾器fetch react Response to p

    這篇文章主要介紹了springboot跨域過濾器fetch react Response to preflight request doesn‘t pass access control check問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • SpringBoot項(xiàng)目中連接Gauss數(shù)據(jù)庫

    SpringBoot項(xiàng)目中連接Gauss數(shù)據(jù)庫

    本文主要介紹了SpringBoot項(xiàng)目中連接Gauss數(shù)據(jù)庫,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-06-06
  • Spring細(xì)數(shù)兩種代理模式之靜態(tài)代理和動態(tài)代理概念及使用

    Spring細(xì)數(shù)兩種代理模式之靜態(tài)代理和動態(tài)代理概念及使用

    代理是一種設(shè)計(jì)模式,提供了對目標(biāo)對象另外的訪問方式,即通過代理對象訪問目標(biāo)對象??梢圆恍薷哪繕?biāo)對象,對目標(biāo)對象功能進(jìn)行拓展。在我們學(xué)習(xí)Spring的時候就會發(fā)現(xiàn),AOP(面向切面編程)的底層就是代理
    2023-02-02
  • Spring的@PreAuthorize注解自定義權(quán)限校驗(yàn)詳解

    Spring的@PreAuthorize注解自定義權(quán)限校驗(yàn)詳解

    這篇文章主要介紹了Spring的@PreAuthorize注解自定義權(quán)限校驗(yàn)詳解,由于項(xiàng)目中,需要對外開放接口,要求做請求頭校驗(yàn),不做其他權(quán)限控制,所以準(zhǔn)備對開放的接口全部放行,不做登錄校驗(yàn),需要的朋友可以參考下
    2023-11-11

最新評論