国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot定時任務動態(tài)擴展ScheduledTaskRegistrar

這篇具有很好參考價值的文章主要介紹了SpringBoot定時任務動態(tài)擴展ScheduledTaskRegistrar。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

摘要:本文主要介紹基于SpringBoot定時任務ScheduledTaskRegistrar的動態(tài)擴展,實現(xiàn)定時任務的動態(tài)新增和刪除。

ScheduledTaskRegistrar類簡要描述

平常使用方式配置

  • Application啟動類上添加注解@EnableScheduling
@EnableScheduling
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
復制代碼
  • 在需要定時的方法上添加定時注解@Scheduled(cron = "0/10 * * * * ?")
@Slf4j
@Component
public class OtherScheduler {

    @Scheduled(cron = "0/10 * * * * ?")
    public void print(){
        log.info("每10S打印一次");
    }

    @Scheduled(cron = "0/5 * * * * ?")
    public void print5(){
        log.info("每5S打印一次");
    }

}
復制代碼

原理分析

默認的方式啟動把ScheduledAnnotationBeanPostProcessor該類實例化到SpringBootBean管理中,并且該類持有一個ScheduledTaskRegistrar屬性,然后掃描出來擁有@Scheduled注解的方法,添加到定時任務中。

  • 添加定時任務到列表中

掃描到@Scheduled注解的時候調(diào)用了該方法添加任務

public void addCronTask(Runnable task, String expression) {
	if (!CRON_DISABLED.equals(expression)) {
		addCronTask(new CronTask(task, expression));
	}
}
復制代碼
  • 啟動定時任務

在對象實例化完成后,調(diào)用了afterPropertiesSet方法,該方法實際使用中執(zhí)行了

public void afterPropertiesSet() {
	scheduleTasks();
}

protected void scheduleTasks() {
	if (this.taskScheduler == null) {
		this.localExecutor = Executors.newSingleThreadScheduledExecutor();
		this.taskScheduler = new ConcurrentTaskScheduler(this.localExecutor);
	}
	if (this.triggerTasks != null) {
		for (TriggerTask task : this.triggerTasks) {
			addScheduledTask(scheduleTriggerTask(task));
		}
	}
	if (this.cronTasks != null) {
		for (CronTask task : this.cronTasks) {
			addScheduledTask(scheduleCronTask(task));
		}
	}
	if (this.fixedRateTasks != null) {
		for (IntervalTask task : this.fixedRateTasks) {
			addScheduledTask(scheduleFixedRateTask(task));
		}
	}
	if (this.fixedDelayTasks != null) {
		for (IntervalTask task : this.fixedDelayTasks) {
			addScheduledTask(scheduleFixedDelayTask(task));
		}
	}
}

private void addScheduledTask(@Nullable ScheduledTask task) {
	if (task != null) {
		this.scheduledTasks.add(task);
	}
}

// 啟動任務核心方法
public ScheduledTask scheduleCronTask(CronTask task) {
	ScheduledTask scheduledTask = this.unresolvedTasks.remove(task);
	boolean newTask = false;
	if (scheduledTask == null) {
		scheduledTask = new ScheduledTask(task);
		newTask = true;
	}
	if (this.taskScheduler != null) {
		scheduledTask.future = this.taskScheduler.schedule(task.getRunnable(), task.getTrigger());
	}
	else {
		addCronTask(task);
		this.unresolvedTasks.put(task, scheduledTask);
	}
	return (newTask ? scheduledTask : null);
}
復制代碼

DynamicScheduledTaskRegistrar動態(tài)任務注冊類

下面改動主要涉及到線程池數(shù)量、新增任務、刪除任務、銷毀任務四個方面;

public class DynamicScheduledTaskRegistrar extends ScheduledTaskRegistrar {

    private static final Logger log = LoggerFactory.getLogger(DynamicScheduledTaskRegistrar.class);

    private final Map<String,ScheduledTask> scheduledTaskMap = new LinkedHashMap<>(16);

    public DynamicScheduledTaskRegistrar(){
        super();
        // 兩種實現(xiàn)方案
        //ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
        //TaskScheduler taskScheduler = new ConcurrentTaskScheduler(scheduledExecutorService);
        // 第二種實現(xiàn)方案
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(8);
        taskScheduler.setRemoveOnCancelPolicy(true);
        taskScheduler.setThreadNamePrefix("dynamic-scheduled-task-");
        taskScheduler.initialize();
        this.setScheduler(taskScheduler);
    }
    /**
     * 新增任務
     * @param taskName
     * @param cron
     * @param runnable
     */
    public Boolean addCronTask(String taskName,String cron,Runnable runnable){
        if(scheduledTaskMap.containsKey(taskName)){
            log.error("定時任務["+ taskName+"]已存在,添加失敗");
            return Boolean.FALSE;
        }
        CronTask cronTask = new CronTask(runnable,cron);
        ScheduledTask scheduledTask = this.scheduleCronTask(cronTask);
        scheduledTaskMap.put(taskName,scheduledTask);
        log.info("定時任務["+taskName+"]新增成功");
        return Boolean.TRUE;
    }

    /**
     * 刪除任務
     * @param taskName
     */
    public void cancelCronTask(String taskName){
        ScheduledTask scheduledTask = scheduledTaskMap.get(taskName);
        if(null != scheduledTask){
            scheduledTask.cancel();
            scheduledTaskMap.remove(taskName);
        }
        log.info("定時任務["+taskName+"]刪除成功");
    }

    @Override
    public void destroy() {
        super.destroy();
        scheduledTaskMap.values().forEach(ScheduledTask::cancel);
    }
}
復制代碼

線程池數(shù)量問題

由于默認是單線程的,如果任務阻塞時間過長則會導致后續(xù)的任務阻塞,所以盡量是異步任務或者是線程池數(shù)量大一點,則可以避免這個問題

DynamicScheduledTaskService

@Service
public class DynamicScheduledTaskService {

    private static final Logger log = LoggerFactory.getLogger(DynamicScheduledTaskService.class);

    private final DynamicScheduledTaskRegistrar dynamicScheduledTaskRegistrar = new DynamicScheduledTaskRegistrar();

    /**
     * 新增任務
     * @param taskName
     * @param cron
     */
    public void add(String taskName,String cron){
        Boolean result = dynamicScheduledTaskRegistrar.addCronTask(taskName,cron,() -> print(taskName));
        log.info("定時任務添加結(jié)果:" + result);
    }

    /**
     * 取消任務
     * @param taskName
     */
    public void cancel(String taskName){
        dynamicScheduledTaskRegistrar.cancelCronTask(taskName);
    }

    private void print(String taskName){
        log.info(taskName+"開始");
        try{
            Thread.sleep(9000L);
            log.info(taskName+"結(jié)束111");
        }catch (Exception ex){

        }
        log.info(taskName+"結(jié)束");
    }

}
復制代碼

SchedulerController

@RestController
@RequestMapping(value = "scheduler")
public class SchedulerController {

    @Autowired
    private DynamicScheduledTaskService dynamicScheduledTaskService;

    @GetMapping(value = "add")
    public Object add(String taskName,String cron){
        dynamicScheduledTaskService.add(taskName,cron);
        return "SUCCESS";
    }

    @GetMapping(value = "cancel")
    public Object cancel(String jobName){
        dynamicScheduledTaskService.cancel(jobName);
        return "SUCCESS";
    }

}
復制代碼

測試結(jié)果

新增的任務都睡眠了9S

新增調(diào)度任務

SpringBoot定時任務動態(tài)擴展ScheduledTaskRegistrar

SpringBoot定時任務動態(tài)擴展ScheduledTaskRegistrar

刪除調(diào)度任務

SpringBoot定時任務動態(tài)擴展ScheduledTaskRegistrar

SpringBoot定時任務動態(tài)擴展ScheduledTaskRegistrar文章來源地址http://www.zghlxwxcb.cn/news/detail-427339.html

到了這里,關(guān)于SpringBoot定時任務動態(tài)擴展ScheduledTaskRegistrar的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務器費用

相關(guān)文章

  • xxl-job定時任務配置應用以及添加到自己已有的springboot項目中實現(xiàn)動態(tài)API調(diào)用

    xxl-job定時任務配置應用以及添加到自己已有的springboot項目中實現(xiàn)動態(tài)API調(diào)用

    XXL-JOB是一個分布式任務調(diào)度平臺,其核心設(shè)計目標是開發(fā)迅速、學習簡單、輕量級、易擴展?,F(xiàn)已開放源代碼并接入多家公司線上產(chǎn)品線,開箱即用。 本篇文章主要是對xuxueli的xxl-job做一個簡單的配置,以及將其添加到自己已有的項目中進行api調(diào)用。 一、xxl-job安裝 1、首先

    2024年02月03日
    瀏覽(19)
  • springboot定時任務:同時使用定時任務和websocket報錯

    springboot定時任務:同時使用定時任務和websocket報錯

    項目使用了websocket,實現(xiàn)了消息的實時推送。后來項目需要一個定時任務,使用org.springframework.scheduling.annotation的@EnableScheduling注解來實現(xiàn),啟動項目之后報錯 打斷點 進入代碼發(fā)現(xiàn)是這個定時任務的bean為null 由于先寫的websocket推送消息,運行正常。之前一個項目只有一個定時任

    2024年02月11日
    瀏覽(26)
  • springboot 與異步任務,定時任務,郵件任務

    springboot 與異步任務,定時任務,郵件任務

    在Java應用中,絕大多數(shù)情況下都是通過同步的方式來實現(xiàn)交互處理的;但是在處理與第三方系統(tǒng)交互的時候,容易造成響應遲緩的情況,之前大部分都是使用多線程來完成此類任務,其實,在Spring 3.x之后,就已經(jīng)內(nèi)置了@Async來完美解決這個問題。 SpringBoot 實現(xiàn)比較簡單 主啟

    2024年02月10日
    瀏覽(29)
  • Quartz實戰(zhàn):基于Quartz實現(xiàn)定時任務的動態(tài)調(diào)度,實現(xiàn)定時任務的增刪改查

    Quartz實戰(zhàn):基于Quartz實現(xiàn)定時任務的動態(tài)調(diào)度,實現(xiàn)定時任務的增刪改查

    Quartz使用文檔,使用Quartz實現(xiàn)動態(tài)任務,Spring集成Quartz,Quartz集群部署,Quartz源碼分析 Quartz使用文檔,使用Quartz實現(xiàn)動態(tài)任務,Spring集成Quartz,Quartz集群部署,Quartz源碼分析 此處省略了SysJob實體類,以及Mapper等對數(shù)據(jù)庫的操作。 本文只是大致實現(xiàn)一個基于Quartz實現(xiàn)定時任務

    2024年02月15日
    瀏覽(23)
  • 【springboot】springboot定時任務:

    【springboot】springboot定時任務:

    一、文檔: 【cron表達式在線生成器】https://cron.qqe2.com/ 二、案例:

    2024年02月11日
    瀏覽(21)
  • Spring Boot動態(tài)設(shè)置定時任務

    Spring Boot動態(tài)設(shè)置定時任務

    ??????? spring boot項目實現(xiàn)定時任務,最簡單的一種就是基于注解 @Schedule 的方式,在啟動類上添加 @EnableScheduling 注解進行標注,就可實現(xiàn)。但是,這個方式有個缺點,那就是執(zhí)行周期寫死在代碼里,無法動態(tài)改變,想要改變只能修改代碼再重新部署啟動。為了能夠動態(tài)的

    2024年02月08日
    瀏覽(21)
  • springboot---定時任務實現(xiàn)

    springboot---定時任務實現(xiàn)

    任意類中創(chuàng)建一個方法,將該方法用@scheduled注解修飾,然后在項目的主方法上添加@EnableScheduling注解,定時任務就會生效。 但是需要注意的是定時任務不會一開始就執(zhí)行,會等待設(shè)定的時間 1.2.1. cron cron表達式是一個字符串,字符串以5或6個空格隔開,分開共6或7個域,每一個

    2024年02月11日
    瀏覽(20)
  • springboot:定時任務

    springboot:定時任務

    目錄 一、實現(xiàn)定時任務的方法一:基于JDK 方法一:使用JDK自帶的Timer類 法二:使用ScheduleExecutorsService類 二、基于Spring Task實現(xiàn)定時任務(推薦使用) ?三、基于Quartz實現(xiàn)定時調(diào)度 四、使用分布式定時任務框架:elastic-job 五、分布式任務調(diào)度:國產(chǎn)組件XXL-Job 定時任務在項目中的

    2024年02月16日
    瀏覽(22)
  • SpringBoot 實現(xiàn)定時任務

    SpringBoot 實現(xiàn)定時任務

    定時任務在實際項目開發(fā)中很常見,并且定時任務可以在各種場景中應用,通過自動化操作和任務的規(guī)模化管理,提高效率、可靠性和工作質(zhì)量??梢詼p少手動操作,避免疏忽和錯誤,并節(jié)省時間和人力資源的投入 簡單易用: 使用注解驅(qū)動的方式,簡化了定時任務的配置和

    2024年02月12日
    瀏覽(32)
  • SpringBoot——Scheduled定時任務

    SpringBoot——Scheduled定時任務

    目錄 1.靜態(tài)定時任務 2.動態(tài)定時任務 在一些業(yè)務場景中,我們需要定義一些任務在我們指定的時間或是每隔一個時間段就自動執(zhí)行,來作為任務的前提,保證業(yè)務的執(zhí)行。比如:我們需要一個定時任務,每天早上6點執(zhí)行,對數(shù)據(jù)庫中的某個日期字段進行修改,修改為當天時

    2023年04月17日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包