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

一文帶你掌握SpringBoot中常見定時任務(wù)的實現(xiàn)

 更新時間:2024年03月07日 09:47:25   作者:碼農(nóng)Academy  
這篇文章主要為大家詳細介紹了Spring?Boot中定時任務(wù)的基本用法、高級特性以及最佳實踐,幫助開發(fā)人員更好地理解和應(yīng)用定時任務(wù),提高系統(tǒng)的穩(wěn)定性和可靠性,需要的可以參考下

引言

在現(xiàn)代軟件開發(fā)中,定時任務(wù)是一種常見的需求,用于執(zhí)行周期性的任務(wù)或在特定的時間點執(zhí)行任務(wù)。這些任務(wù)可能涉及數(shù)據(jù)同步、數(shù)據(jù)備份、報表生成、緩存刷新等方面,對系統(tǒng)的穩(wěn)定性和可靠性有著重要的影響。Spring Boot提供了強大且簡單的定時任務(wù)功能,使開發(fā)人員能夠輕松地管理和執(zhí)行這些任務(wù)。

本文將介紹 Spring Boot中定時任務(wù)的基本用法、高級特性以及最佳實踐,幫助開發(fā)人員更好地理解和應(yīng)用定時任務(wù),提高系統(tǒng)的穩(wěn)定性和可靠性。

SpringBoot中的定時任務(wù)

SpringBoot中的定時任務(wù)主要通過@Scheduled注解以及SchedulingConfigurer接口實現(xiàn)。

@Scheduled注解

@Scheduled注解是Spring提供的一個注解,用于標(biāo)記方法作為定時任務(wù)執(zhí)行。通過 @Scheduled注解,開發(fā)人員可以輕松地配置方法在指定的時間間隔或時間點執(zhí)行,實現(xiàn)各種定時任務(wù)需求。

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
@Repeatable(Schedules.class)  
public @interface Scheduled {

	String cron() default "";

	long fixedDelay() default -1;

	long fixedRate() default -1;

	long initialDelay() default -1;
}

以上為@Scheduled源碼中關(guān)鍵屬性,各屬性含義如下:

cron: 接受標(biāo)準(zhǔn)的Unix Cron表達式,用于定義復(fù)雜的計劃執(zhí)行時間。

/**  
* cron屬性可以設(shè)置指定時間執(zhí)行,cron表達式跟linux一樣  
*/  
@Scheduled(cron = "0 45 14 ? * *")  
public void fixTimeExecution() {  
	System.out.println("指定時間 "+dateFormat.format(new Date())+"執(zhí)行");  
}

fixedRate: 以固定的頻率執(zhí)行任務(wù),指定兩次執(zhí)行之間的間隔時間(單位是毫秒)。

/**  
* fixedRate屬性設(shè)置每隔固定時間執(zhí)行  
*/  
@Scheduled(fixedRate = 5000)  
public void reportCurrentTime() {  
	System.out.println("每隔五秒執(zhí)行一次" + dateFormat.format(new Date())); 
}

fixedDelay:在每次任務(wù)完成后等待一定的時間再進行下一次執(zhí)行,指定連續(xù)執(zhí)行之間的延遲時間。

/**  
* 上一次任務(wù)執(zhí)行完成之后10秒后在執(zhí)行  
*/  
@Scheduled(fixedDelay = 10000)  
public void runWithFixedDelay() {  
	System.out.println("指定時間 "+dateFormat.format(new Date())+"執(zhí)行");  
}

initialDelay:首次執(zhí)行前的延遲時間。

/**  
* 初始延遲1秒后開始,然后每10秒執(zhí)行一次  
*/  
@Scheduled(initialDelay=1000, fixedDelay=10000)  
public void executeWithInitialAndFixedDelay() {  
	System.out.println("指定時間 "+dateFormat.format(new Date())+"執(zhí)行");  
}

這里要注意fixedRate與fixedDelay的區(qū)別:fixedRate是基于任務(wù)開始執(zhí)行的時間點來計算下一次任務(wù)開始執(zhí)行的時間,因此任務(wù)的執(zhí)行時間間隔是相對固定的,不受到任務(wù)執(zhí)行時間的影響。如果指定的時間間隔小于任務(wù)執(zhí)行的實際時間,則任務(wù)可能會并發(fā)執(zhí)行。而fixedDelay是基于任務(wù)執(zhí)行完成的時間點來計算下一次任務(wù)開始執(zhí)行的時間,因此任務(wù)的執(zhí)行時間間隔是相對不規(guī)則的,受到任務(wù)執(zhí)行時間的影響。

SpringBoot支持同時定義多個定時任務(wù)方法,每個方法可以使用不同的參數(shù)配置,以滿足不同的定時任務(wù)需求。同時,我們必須在配置類中使用@EnableScheduling注解開啟定時任務(wù)。

@Configuration  
@EnableScheduling  
public class ScheduledTaskConfig { 

}

或者

@EnableScheduling  
@SpringBootApplication  
public class SpringBootBaseApplication {  
  
    public static void main(String[] args) {  
       SpringApplication.run(SpringBootBaseApplication.class, args);  
    }  
}

在SpringBoot應(yīng)用程序中,除了在代碼中使用注解配置定時任務(wù)外,還可以通過配置文件來配置定時任務(wù)的執(zhí)行規(guī)則。這種方式更加靈活,可以在不修改源代碼的情況下,動態(tài)調(diào)整定時任務(wù)的執(zhí)行規(guī)則。比如我們在application.properties中配置@Scheduled的屬性:

custom.scheduled.cron = 0/5 * * * * ?  
custom.scheduled.fixedRate=5000  
custom.scheduled.fixedDelay=10000  
custom.scheduled.initialDelay=1000

然后在@Scheduled的方法使用屬性配置定時任務(wù)執(zhí)行頻率。

@Service  
public class DemoScheduledTaskService {  
  
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");  
  
    /**  
     * fixedRate屬性設(shè)置每隔固定時間執(zhí)行  
     */  
    @Scheduled(fixedRateString = "${custom.scheduled.fixedRate}")  
    public void reportCurrentTime() {  
        System.out.println("每隔五秒執(zhí)行一次" + dateFormat.format(new Date()));  
    }  
  
    /**  
     * cron屬性可以設(shè)置指定時間執(zhí)行,cron表達式跟linux一樣  
     */  
    @Scheduled(cron = "${custom.scheduled.cron}")  
    public void fixTimeExecution() {  
        System.out.println("指定時間 "+dateFormat.format(new Date())+"執(zhí)行");  
    }  
  
    /**  
     * 上一次任務(wù)執(zhí)行完成之后10秒后在執(zhí)行  
     */  
    @Scheduled(fixedDelayString = "${custom.scheduled.fixedDelay}")  
    public void runWithFixedDelay() {  
        System.out.println("指定時間 "+dateFormat.format(new Date())+"執(zhí)行");  
    }  
  
    /**  
     * 初始延遲1秒后開始,然后每10秒執(zhí)行一次  
     */  
    @Scheduled(initialDelayString = "${custom.scheduled.initialDelay}", fixedDelayString = "${custom.scheduled.fixedDelay}")  
    public void executeWithInitialAndFixedDelay() {  
        System.out.println("指定時間 "+dateFormat.format(new Date())+"執(zhí)行");  
    }  
}

注意,這里使用屬性來指定任務(wù)執(zhí)行頻率時,要通過@Scheduled的fixedRateString、fixedDelayString、initialDelayString三個可以指定字符串的值的屬性去指定,效果等同于long類型的屬性。

通過配置文件配置定時任務(wù)具有很高的靈活性,可以在不重新編譯和部署應(yīng)用程序的情況下,隨時調(diào)整定時任務(wù)的執(zhí)行規(guī)則。同時,也可以根據(jù)不同的環(huán)境(例如開發(fā)、測試、生產(chǎn))配置不同的定時任務(wù)規(guī)則,以滿足不同環(huán)境下的需求。這種方式可以有效地解耦定時任務(wù)的配置和業(yè)務(wù)代碼,提高系統(tǒng)的靈活性和可維護性。

另外,如果希望定時任務(wù)能夠異步執(zhí)行,不阻塞主線程,可以在方法上同時加上@Async注解,這樣各任務(wù)就可以異步執(zhí)行了。有關(guān)SpringBoot中使用@Async的講解,請移步:

雖然 @Scheduled 注解是一個方便的方式來定義定時任務(wù),但它也存在一些弊端。因為任務(wù)的執(zhí)行計劃(如cron表達式)在編譯時被硬編碼,因此無法在運行時動態(tài)修改,除非重新部署。此外,@Scheduled注解對于配置不同的調(diào)度策略(如使用不同的線程池)顯得力不從心,而且默認情況下,@Scheduled任務(wù)在單線程環(huán)境下執(zhí)行,可能出現(xiàn)任務(wù)堆積的情況,尤其在任務(wù)量大或任務(wù)執(zhí)行時間長的情況下,而且這些任務(wù)可能會變得混亂和難以管理。定時任務(wù)的配置分散在各個任務(wù)方法中,不利于統(tǒng)一管理和維護。對于需要根據(jù)動態(tài)條件創(chuàng)建或銷毀定時任務(wù)的情況,@Scheduled注解也無法滿足需求。

為了解決這些問題,可以使用SchedulingConfigurer接口來動態(tài)地創(chuàng)建和管理定時任務(wù)。通過實現(xiàn) SchedulingConfigurer 接口,我們可以編寫代碼來動態(tài)地注冊和管理定時任務(wù),從而實現(xiàn)靈活的任務(wù)調(diào)度需求。接下來,我們將介紹如何使用SchedulingConfigurer接口來創(chuàng)建定時任務(wù)。

SchedulingConfigurer接口

SchedulingConfigurer 接口是 Spring 提供的一個用于定時任務(wù)配置的擴展接口,它允許開發(fā)人員更細粒度地控制定時任務(wù)的執(zhí)行。通過實現(xiàn)SchedulingConfigurer接口,可以自定義任務(wù)調(diào)度器(TaskScheduler),配置線程池等參數(shù),以滿足不同場景下的定時任務(wù)需求。

@Configuration  
@EnableScheduling  
public class CustomSchedulingConfig implements SchedulingConfigurer {

	@Override  
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		// 定時任務(wù)邏輯
	}
}

通過實現(xiàn)SchedulingConfigurer接口,重寫configureTasks方法,自定義任務(wù)調(diào)度器的配置。此外我們還可以配置線程池,用于控制定時任務(wù)執(zhí)行時的線程數(shù)量、并發(fā)性等參數(shù)。

@Bean(destroyMethod = "shutdown")  
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {  
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();  
    scheduler.setPoolSize(5); // 設(shè)置線程池大小  
    scheduler.setThreadNamePrefix("scheduled-task-"); // 設(shè)置線程名稱前綴  
    scheduler.setAwaitTerminationSeconds(60); // 設(shè)置終止等待時間  
	// 設(shè)置處理拒絕執(zhí)行的任務(wù)異常
	scheduler.setRejectedExecutionHandler((r, executor) -> log.error("Task rejected", r));
	// 處理定時任務(wù)執(zhí)行過程中拋出的未捕獲異常
	scheduler.setErrorHandler(e -> log.error("Error in scheduled task", e));
    return scheduler;  
}

然后將自定義的ThreadPoolTaskScheduler設(shè)置到ScheduledTaskRegistrar中去:

@Override  
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
	// 定時任務(wù)邏輯
	taskRegistrar.setTaskScheduler(threadPoolTaskScheduler());
}

有關(guān)線程池的配置參數(shù)講解,請移步:

通過SchedulingConfigurer接口,可以更靈活地配置任務(wù)調(diào)度器和定時任務(wù)的執(zhí)行規(guī)則,比如動態(tài)注冊定時任務(wù)、動態(tài)修改任務(wù)執(zhí)行規(guī)則等。

動態(tài)添加定時任務(wù)

SchedulingConfigurerconfigureTasks方法中,我們可以根據(jù)業(yè)務(wù)需求,從數(shù)據(jù)庫、配置文件或其它動態(tài)來源獲取定時任務(wù)的信息(如Cron表達式、任務(wù)執(zhí)行類等),然后創(chuàng)建對應(yīng)的RunnableCallable實例,并結(jié)合Trigger(如CronTrigger)將其添加到調(diào)度器中。相比@Scheduled注解,這種方式能夠在應(yīng)用運行時隨時添加新的定時任務(wù)。

@Override  
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {  
    ThreadPoolTaskScheduler scheduler = threadPoolTaskScheduler();  
    taskRegistrar.setTaskScheduler(scheduler);  
  
    List<CronTaskInfo> tasksFromDB = listTasksFromDatabase();  
  
    for (CronTaskInfo task : tasksFromDB) {  
        Runnable taskRunner = new MyTaskExecutor(task.getTaskData());  
        CronTrigger cronTrigger = new CronTrigger(task.getCronExpression());  
        scheduler.schedule(taskRunner, cronTrigger);  
    }  
}

關(guān)于這里在應(yīng)用運行時,動態(tài)的添加新的任務(wù),我們可以通過事件驅(qū)動,輪訓(xùn)檢查,消息隊列等多種方式,監(jiān)聽到數(shù)據(jù)庫中或者配置文件中新增任務(wù)信息,然后通過SchedulingConfigurer接口動態(tài)創(chuàng)建定時任務(wù)。而這種方式是@Scheduled注解做不到的。

修改定時任務(wù)規(guī)則

當(dāng)任務(wù)的執(zhí)行規(guī)則需要動態(tài)變更時,同樣可以在configureTasks方法中實現(xiàn)。例如,從數(shù)據(jù)庫獲取最新的Cron表達式,然后取消當(dāng)前任務(wù)并重新添加新的任務(wù)實例。需要注意的是,取消已有任務(wù)通常需要持有對該任務(wù)的引用,例如使用Scheduler提供的unschedule方法。

// 假設(shè)我們有一個方法用于獲取更新后的任務(wù)信息  
CronTaskInfo updatedTask = getUpdatedTaskInfoFromDatabase();  
  
// 取消舊的任務(wù)(需要知道舊任務(wù)的TriggerKey)  
TriggerKey triggerKey = ...; // 獲取舊任務(wù)的TriggerKey  
scheduler.unschedule(triggerKey);  
  
// 創(chuàng)建新任務(wù)并設(shè)置新的Cron表達式  
MyTaskExecutor taskExecutor = new MyTaskExecutor(updatedTask.getTaskData());  
CronTrigger updatedCronTrigger = new CronTrigger(updatedTask.getCronExpression());  
  
// 重新調(diào)度新任務(wù)  
scheduler.schedule(taskRunner, updatedCronTrigger);

另外,我們還可以通過添加任務(wù)時對其排序或設(shè)置優(yōu)先級等方式間接實現(xiàn)設(shè)置定時任務(wù)的執(zhí)行順序。

通過實現(xiàn)SchedulingConfigurer接口,我們可以擁有對定時任務(wù)調(diào)度的更多控制權(quán),比如自定義線程池、動態(tài)添加任務(wù)以及調(diào)整任務(wù)執(zhí)行策略。這種靈活性使得在復(fù)雜環(huán)境下,特別是需要動態(tài)管理定時任務(wù)時,SchedulingConfigurer成為了理想的選擇。

其他第三方任務(wù)調(diào)度框架

除了使用Spring框架提供的 @Scheduled 注解和SchedulingConfigurer接口外,還有許多第三方的任務(wù)調(diào)度庫可供選擇。這些庫通常提供了更多的功能和靈活性,以滿足各種復(fù)雜的任務(wù)調(diào)度需求。以下是一些常見的第三方任務(wù)調(diào)度庫:

Quartz Scheduler

Quartz是一個功能強大且靈活的任務(wù)調(diào)度庫,具有豐富的功能,如支持基于cron表達式的任務(wù)調(diào)度、集群支持、作業(yè)持久化等。它可以與Spring框架集成,并且被廣泛應(yīng)用于各種類型的任務(wù)調(diào)度應(yīng)用程序中。

Elastic Job

Elastic Job是一個分布式任務(wù)調(diào)度框架,可以輕松實現(xiàn)分布式任務(wù)調(diào)度和作業(yè)執(zhí)行。它提供了分布式任務(wù)執(zhí)行、作業(yè)依賴關(guān)系、作業(yè)分片等功能,適用于大規(guī)模的分布式任務(wù)調(diào)度場景。

xxl-job

xxl-job是一個分布式任務(wù)調(diào)度平臺,提供了可視化的任務(wù)管理界面和多種任務(wù)調(diào)度方式,如單機任務(wù)、分布式任務(wù)、定時任務(wù)等。它支持任務(wù)執(zhí)行日志、任務(wù)失敗重試、動態(tài)調(diào)整任務(wù)執(zhí)行策略等功能。

PowerJob

PowerJob是一個開源的分布式任務(wù)調(diào)度框架,由阿里巴巴集團開發(fā)并開源。PowerJob 提供了分布式、高可用的任務(wù)調(diào)度能力,支持多種任務(wù)類型,如定時任務(wù)、延時任務(wù)、流程任務(wù)等。

總結(jié)

定時任務(wù)在現(xiàn)代軟件開發(fā)中扮演著重要的角色,它們可以自動化執(zhí)行各種重復(fù)性的任務(wù),提高系統(tǒng)的效率和可靠性。SpringBoot提供了強大而靈活的定時任務(wù)功能,使我們能夠輕松地管理和執(zhí)行各種定時任務(wù)。通過@Scheduled注解和SchedulingConfigurer接口,我們可以根據(jù)需求配置定時任務(wù)的執(zhí)行規(guī)則,實現(xiàn)各種復(fù)雜的定時任務(wù)調(diào)度需求。我們可以充分利用SpringBoot中的定時任務(wù)功能,提高系統(tǒng)的穩(wěn)定性和可靠性,從而更好地滿足業(yè)務(wù)需求。

到此這篇關(guān)于一文帶你掌握SpringBoot中常見定時任務(wù)的實現(xiàn)的文章就介紹到這了,更多相關(guān)SpringBoot定時任務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入理解Java 線程通信

    深入理解Java 線程通信

    這篇文章主要介紹了Java 線程通信的的相關(guān)資料,文中講解非常細致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06
  • Java對象的XML序列化與反序列化實例解析

    Java對象的XML序列化與反序列化實例解析

    這篇文章主要介紹了Java對象的XML序列化與反序列化實例解析,小編覺得還是挺不錯的,這里分享給大家。
    2017-10-10
  • java中的switch case語句使用詳解

    java中的switch case語句使用詳解

    這篇文章主要介紹了java中的switch case語句使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java導(dǎo)入、導(dǎo)出excel用法步驟保姆級教程(附封裝好的工具類)

    Java導(dǎo)入、導(dǎo)出excel用法步驟保姆級教程(附封裝好的工具類)

    這篇文章主要介紹了Java導(dǎo)入、導(dǎo)出excel的相關(guān)資料,講解了使用Java和ApachePOI庫將數(shù)據(jù)導(dǎo)出為Excel文件,包括創(chuàng)建工作簿、工作表、行和單元格,設(shè)置樣式和字體,合并單元格,添加公式和下拉選擇等功能,需要的朋友可以參考下
    2025-03-03
  • Java中資源加載的方法及Spring的ResourceLoader應(yīng)用小結(jié)

    Java中資源加載的方法及Spring的ResourceLoader應(yīng)用小結(jié)

    在Java開發(fā)中,資源加載是一個基礎(chǔ)而重要的操作,這篇文章主要介紹了深入理解Java中資源加載的方法及Spring的ResourceLoader應(yīng)用,本文通過實例代碼演示了通過ClassLoader和Class獲取資源的內(nèi)容,以及使用Spring的ResourceLoader加載多個資源的過程,需要的朋友可以參考下
    2024-01-01
  • kaptcha驗證碼使用方法詳解

    kaptcha驗證碼使用方法詳解

    這篇文章主要為大家詳細介紹了kaptcha驗證碼的使用方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • Java結(jié)合Kotlin實現(xiàn)寶寶年齡計算

    Java結(jié)合Kotlin實現(xiàn)寶寶年齡計算

    這篇文章主要為大家介紹了Java結(jié)合Kotlin實現(xiàn)寶寶年齡計算示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • java日志門面之JCL和SLF4J詳解

    java日志門面之JCL和SLF4J詳解

    這篇文章主要給大家介紹了關(guān)于java日志門面之JCL和SLF4J的相關(guān)資料,在系統(tǒng)開發(fā)過程中日志框架的選擇與更換是一大挑戰(zhàn),日志門面的概念,如JCL和SLF4J,允許開發(fā)者面向接口編程,文中介紹的非常詳細,需要的朋友可以參考下
    2024-10-10
  • springcloud項目快速開始起始模板的實現(xiàn)

    springcloud項目快速開始起始模板的實現(xiàn)

    本文主要介紹了springcloud項目快速開始起始模板思路的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • Java中常見字符串拼接九種方式詳細例子

    Java中常見字符串拼接九種方式詳細例子

    這篇文章主要給大家介紹了關(guān)于Java中常見字符串拼接的九種方式,字符串拼接是我們在Java代碼中比較經(jīng)常要做的事情,就是把多個字符串拼接到一起,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-07-07

最新評論