Spring Boot從入門到實戰(十) 非同步處理

2022-07-04 03:39:17 字數 3662 閱讀 5980

在spring boot中,或者說在spring中,我們實現非同步處理一般有以下幾種方式:

1. 通過 @enableasync 與 @asyc 註解結合實現

2. 通過非同步事件實現

3. 通過訊息佇列實現

<

task:annotation-driven

executor

="executor"

/>

<

task:executor

id="executor"

pool-size

="10-200"

queue-capacity

="2000"

/>

spring的 @enableasync 註解的功能與類似,將其新增於乙個 @configuration 配置類上,可對spring應用的上下文開啟非同步方法支援。 @async 註解可以標註在方法或類上,表示某個方法或某個類裡的所有方法需要通過非同步方式來呼叫。 

1. 新增 @enableasync 註解

在乙個 @configuration 配置類上新增 @enableaysnc 註解,我們一般可以新增到啟動類上,如

@enableasync

public

class

public

static

void

main(string args)

}2. 配置相關的非同步執行執行緒池 

@configuration

public

class asyncconfig implements

asyncconfigurer ")

private

intcorepoolsize;

@value("$")

private

intmaxpoolsize;

@value("$")

private

intqueuecapacity;

@value("$")

private

intkeepalive;

public

executor getasyncexecutor()

public

asyncuncaughtexceptionhandler getasyncuncaughtexceptionhandler()

public

static

class myasyncuncaughtexceptionhandler implements

asyncuncaughtexceptionhandler

}}

可通過配置類的方式對非同步執行緒池進行配置,並提供非同步執行時出現異常的處理方法,如

這裡我們通過實現 asyncconfigurer 介面提供了乙個非同步執行執行緒池物件,各引數的說明可以參考【執行緒池的基本原理,看完就懂了】,裡面有很詳細的介紹。且通過實現 asyncuncaughtexceptionhandler 介面提供了乙個非同步執行過程中未捕獲異常的處理類。 

3. 定義非同步方法

非同步方法的定義只需要在類(類上註解表示該類的所有方法都非同步執行)或方法上新增 @async 註解即可,如

@service

public

class

asyncservice

@async

public

void

asyncmethodwithexception()

}

4. 測試

我們可以通過如下測試類來對非同步方法進行測試

@runwith(springrunner.class

)@springboottest

public

class

annotationbasedasynctest

@test

public

void testaysncwithexception() throws

interruptedexception

}

因為非同步方法在乙個新的執行緒中執行,可能在主線程執行完後還沒來得及處理,所以通過sleep來等待它執行完成。具體執行結果讀者可自行嘗試執行,這裡就不貼圖了。

第二種方式是通過spring框架的事件監聽機制實現,但spring的事件監聽預設是同步執行的,所以實際上還是需要借助 @enableasync 與 @async 來實現非同步。

1. 新增 @enableasync 註解

與上同,可新增到啟動類上。

2. 自定義事件類

public

class myevent extends

private

string arg;

public

myevent(object source, string arg)

//getter/setter

}

3. 定義事件處理類

@component

@async

public

public

void

system.out.println("2. running in thread: " +thread.currentthread().getname());

system.out.println("2. arg value: " +event.getarg());

}}

二是通過 @eventlistener 註解,如下

@component

public

class

myeventhandler2

}

注意兩者都需要新增 @async 註解,否則預設是同步方式執行。 

4. 定義事件傳送類

@component

public

class myeventpublisher implements

protected

public

void

}public

void

this

}}

5. 測試

可以通過如下測試類來進行測試,

@runwith(springrunner.class

)@springboottest

public

class

eventbasedasynctest

}

執行後發現兩個事件處理類都執行了,因為兩者都監聽了同乙個事件 myevent 。 

以上兩種方式都是基於伺服器本機執行,如果服務程序出現異常退出,可能導致非同步執行中斷。如果需要保證任務執行的可靠性,可以借助訊息佇列的持久化與重試機制。阿里雲上的訊息佇列服務提供了幾種型別的訊息支援,如順序訊息、定時/延時訊息、事務訊息等(詳情可參考: ),如果專案是基於阿里雲部署的,可以考慮使用其中一類訊息服務來實現業務需求。

Spring Boot從入門到放棄 RESTful

restful是一種網路應用程式的設計風格和開發方式,基於http,可以使用xml格式定義或json格式定義。restful適用於移動網際網路廠商作為業務使能介面的場景,實現第三方ott呼叫流動網路資源的功能,動作型別為新增 變更 刪除所呼叫資源。1 每乙個uri代表1種資源 2 客戶端使用get ...

Spring Boot從入門到高階教程系列目錄

由於前些日子比較忙著一些工作事情,導致沒有更新連續性的教程文章,現在往後一段時間我打算寫當下比較流行的spring boot框架教程 持續更新ing 從入門到高階,其中包含如何優雅設計你的系統結構,如何加強你的系統安全設計等等,希望該系列文章對大家有一些開發上的幫助,本系列教程需要有一定的開發經驗基...

Redis從入門到入門

2安裝1.1支援的儲存結構 remote dictionary server 以字典儲存資料,允許其他應用通過tcp協議訪問字典內容。支援的鍵值型別 優點 redis的字典儲存方式和多重鍵值儲存方式,使得程式設計師可以直接將程式中的資料對映到redis中,資料在redis中的儲存方式和其在程式中的儲...