最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文帶你掌握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提供的一個注解,用于標記方法作為定時任務(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: 接受標準的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ī)則

當任務(wù)的執(zhí)行規(guī)則需要動態(tài)變更時,同樣可以在configureTasks方法中實現(xiàn)。例如,從數(shù)據(jù)庫獲取最新的Cron表達式,然后取消當前任務(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)知識。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-02-02
  • Java 通過位運算求一個集合的所有子集方法

    Java 通過位運算求一個集合的所有子集方法

    下面小編就為大家?guī)硪黄狫ava 通過位運算求一個集合的所有子集方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java實現(xiàn)文件圖片的預(yù)覽和下載功能

    Java實現(xiàn)文件圖片的預(yù)覽和下載功能

    這篇文章主要為大家詳細介紹了如何使用Java實現(xiàn)文件圖片的預(yù)覽和下載功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • jdk源碼閱讀Collection詳解

    jdk源碼閱讀Collection詳解

    這篇文章主要介紹了jdk源碼閱讀Collection詳解,具有一定借鑒價值,需要的朋友可以參考下
    2017-12-12
  • 使用開源項目JAVAE2 進行視頻格式轉(zhuǎn)換

    使用開源項目JAVAE2 進行視頻格式轉(zhuǎn)換

    這篇文章主要介紹了使用開源項目JAVAE 進行視頻格式轉(zhuǎn)換,幫助大家更好的利用Java處理視頻,完成自身需求,感興趣的朋友可以了解下
    2020-11-11
  • Java如何優(yōu)雅地避免空指針異常(NullPointerException)

    Java如何優(yōu)雅地避免空指針異常(NullPointerException)

    這篇文章主要給大家介紹了關(guān)于Java如何優(yōu)雅地避免空指針異常(NullPointerException)的相關(guān)資料,空指針異常(NullPointerException)是一種常見的運行時異常,它在Java編程中經(jīng)常出現(xiàn),需要的朋友可以參考下
    2024-03-03
  • mybatis自動掃描和自定義類注解方式

    mybatis自動掃描和自定義類注解方式

    這篇文章主要介紹了mybatis自動掃描和自定義類注解方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring中Bean的作用域和自動裝配方式

    Spring中Bean的作用域和自動裝配方式

    這篇文章主要介紹了Spring中Bean的作用域和自動裝配方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot集成ELK實現(xiàn)數(shù)據(jù)存儲和日志管理的代碼示例

    SpringBoot集成ELK實現(xiàn)數(shù)據(jù)存儲和日志管理的代碼示例

    本文介紹在SpringBoot 2.7.18中集成Elasticsearch、Logstash、Kibana的步驟,簡單展示了ES增刪改查的API用法,測試Logstash日志收集,并實現(xiàn)Kibana數(shù)據(jù)看板可視化分析日志,需要的朋友可以參考下
    2025-09-09
  • idea2020.1.3 手把手教你創(chuàng)建web項目的方法步驟

    idea2020.1.3 手把手教你創(chuàng)建web項目的方法步驟

    這篇文章主要介紹了idea 2020.1.3 手把手教你創(chuàng)建web項目的方法步驟,文中通過圖文介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評論

平乐县| 通化市| 锦屏县| 洪江市| 兴国县| 双峰县| 通州区| 峨眉山市| 高雄市| 原阳县| 固阳县| 林西县| 惠州市| 偃师市| 渝北区| 辰溪县| 梓潼县| 会同县| 淮阳县| 鲁甸县| 瑞昌市| 永宁县| 凤城市| 天等县| 和政县| 昂仁县| 宾川县| 囊谦县| 澄城县| 木兰县| 吴旗县| 昌吉市| 泰和县| 岳阳市| 棋牌| 新巴尔虎右旗| 福州市| 海晏县| 阳城县| 延长县| 凤城市|