SpringBoot異步方法捕捉異常詳解
本文實(shí)例為大家分享了SpringBoot異步方法捕捉異常的具體代碼,供大家參考,具體內(nèi)容如下
由于項(xiàng)目中定時(shí)器都采用異步執(zhí)行方式
需要定時(shí)監(jiān)控異步方法執(zhí)行進(jìn)度,異常情況
1 執(zhí)行進(jìn)度
可以設(shè)置是否在執(zhí)行,內(nèi)存中添加執(zhí)行標(biāo)識(shí)即可。
防止多次執(zhí)行可以通過(guò)攔截器對(duì)此,標(biāo)識(shí)來(lái)判斷,防止多次執(zhí)行定時(shí)器
2 異常捕捉
監(jiān)控異步方法執(zhí)行是否異常。
1 無(wú)返回值
配置AsyncExceptionConfig類(lèi),統(tǒng)一處理。
定義異常捕獲配置類(lèi)AsyncExceptionConfig,配置類(lèi)里面定義SpringAsyncExceptionHandler 方法實(shí)現(xiàn)AsyncUncaughtExceptionHandler 接口。
代碼如下:
package cn.bwjf.config;
import cn.bwjf.common.constant.InitServiceIdEnum;
import cn.bwjf.common.tools.InitServiceUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
/**
* @description : 異常捕獲配置類(lèi)
* @author : tizzy <br/>
* @version : 1.0
* @date 2019/9/21
*/
@Configuration
@Slf4j
public class AsyncExceptionConfig implements AsyncConfigurer {
/**
* @description : 設(shè)置異步方法線程參數(shù)
* @author : tizzy
* @version : 1.0
*/
@Bean
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//根據(jù)自己機(jī)器配置
executor.setCorePoolSize(8);
executor.setMaxPoolSize(16);
executor.setQueueCapacity(64);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setThreadNamePrefix("SpringAsyncThread-");
return executor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new SpringAsyncExceptionHandler();
}
class SpringAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable throwable, Method method, Object... objects) {
log.info("------我是Async無(wú)返回方法的異常處理方法---------");
//通過(guò)反射獲取各個(gè)初始化方法名字
String methodName = method.getName();
log.info(" 當(dāng)前異常方法名 == {} " , methodName);
//根據(jù)方法名字 記錄異常 略。。。。
log.info("------我是Async無(wú)返回方法的異常處理方法---------");
}
}
}
2 有返回值
返回值 用 AsyncResult 包裝返回
AsyncResult是Future接口的子類(lèi),所以也可以通過(guò)future.get()獲取返回值的時(shí)候捕獲ExcecutionException。
@Async
public Future<String> asyncMethod() {
try {
Thread.sleep(5000);
return new AsyncResult<String>("hello world !!!!");
} catch (InterruptedException e) {
//
}
return null;
}
調(diào)用
try {
Future future = service.asyncMethod();
future.get();
} catch (ExecutionException e) {
logger.error("exception occurs", e);
} catch (InterruptedException e) {
logger.error("exception occurs", e);
}
什么是 Future類(lèi)型?
Future是對(duì)于具體的 Runnable或者 Callable任務(wù)的執(zhí)行結(jié)果進(jìn)行取消、查詢(xún)是否完成、獲取結(jié)果的接口。必要時(shí)可以通過(guò)get方法獲取執(zhí)行結(jié)果,該方法會(huì)阻塞直到任務(wù)返回結(jié)果。
它的接口定義如下:
public interface Future<V> {
boolean cancel(boolean mayInterruptIfRunning);
boolean isCancelled();
boolean isDone();
V get() throws InterruptedException, ExecutionException;
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
}
它聲明這樣的五個(gè)方法:
cancel方法用來(lái)取消任務(wù),如果取消任務(wù)成功則返回true,如果取消任務(wù)失敗則返回false。參數(shù)mayInterruptIfRunning表示是否允許取消正在執(zhí)行卻沒(méi)有執(zhí)行完畢的任務(wù),如果設(shè)置true,則表示可以取消正在執(zhí)行過(guò)程中的任務(wù)。如果任務(wù)已經(jīng)完成,則無(wú)論mayInterruptIfRunning為true還是false,此方法肯定返回false,即如果取消已經(jīng)完成的任務(wù)會(huì)返回false;如果任務(wù)正在執(zhí)行,若mayInterruptIfRunning設(shè)置為true,則返回true,若mayInterruptIfRunning設(shè)置為false,則返回false;如果任務(wù)還沒(méi)有執(zhí)行,則無(wú)論mayInterruptIfRunning為true還是false,肯定返回true。
isCancelled方法表示任務(wù)是否被取消成功,如果在任務(wù)正常完成前被取消成功,則返回 true。
isDone方法表示任務(wù)是否已經(jīng)完成,若任務(wù)完成,則返回true;
get()方法用來(lái)獲取執(zhí)行結(jié)果,這個(gè)方法會(huì)產(chǎn)生阻塞,會(huì)一直等到任務(wù)執(zhí)行完畢才返回;
get(long timeout, TimeUnit unit)用來(lái)獲取執(zhí)行結(jié)果,如果在指定時(shí)間內(nèi),還沒(méi)獲取到結(jié)果,就直接返回null。
也就是說(shuō)Future提供了三種功能:
判斷任務(wù)是否完成;
能夠中斷任務(wù);
能夠獲取任務(wù)執(zhí)行結(jié)果。
3 異步方法中事務(wù)
@Async調(diào)用中的事務(wù)處理機(jī)制
在@Async標(biāo)注的方法,同時(shí)也適用了@Transactional進(jìn)行了標(biāo)注;在其調(diào)用數(shù)據(jù)庫(kù)操作之時(shí),將無(wú)法產(chǎn)生事務(wù)管理的控制,原因就在于其是基于異步處理的操作。
正確做法
如何給這些操作添加事務(wù)管理呢?可以將需要事務(wù)管理操作的方法放置到異步方法內(nèi)部,在內(nèi)部被調(diào)用的方法上添加@Transactional.
例如:
方法A,使用了@Async/@Transactional來(lái)標(biāo)注,但是無(wú)法產(chǎn)生事務(wù)控制的目的。
方法B,使用了@Async來(lái)標(biāo)注, B中調(diào)用了C、D,C/D分別使用@Transactional做了標(biāo)注,是可以實(shí)現(xiàn)事務(wù)控制的目的。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot中API接口參數(shù)獲取方式小結(jié)
在Spring Boot中,API接口參數(shù)可以通過(guò)多種方式獲取,具體取決于你定義的API接口參數(shù)類(lèi)型(如路徑參數(shù)、查詢(xún)參數(shù)、請(qǐng)求體參數(shù)、請(qǐng)求頭等),本文給大家就介紹了一些常見(jiàn)的參數(shù)獲取方式,需要的朋友可以參考下2024-06-06
關(guān)于FastJson?long?溢出問(wèn)題的小結(jié)
這篇文章主要介紹了關(guān)于FastJson?long?溢出問(wèn)題的小結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2022-01-01
Java實(shí)現(xiàn)字符編碼轉(zhuǎn)換(utf-8/gbk)
這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)字符編碼轉(zhuǎn)換工具,主要針對(duì)UTF-8和GBK兩種編碼格式,文中的示例代碼講解詳,需要的可以了解下2025-03-03
idea注解參數(shù)換行時(shí)間日期格式設(shè)置方法
這篇文章主要介紹了idea注解參數(shù)換行時(shí)間日期格式設(shè)置方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05
SpringBoot應(yīng)用自定義logback日志詳解
默認(rèn)情況下,SpringBoot內(nèi)部使用logback作為系統(tǒng)日志實(shí)現(xiàn)的框架,將日志輸出到控制臺(tái),不會(huì)寫(xiě)到日志文件。本篇文章主要講解下如何自定義logabck.xml以及對(duì)logback文件中配置做一個(gè)詳解,需要的可以參考一下2022-10-10
SpringBoot logback日志框架使用過(guò)程解析
這篇文章主要介紹了SpringBoot logback日志框架使用過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
關(guān)于Java跨域Json字符轉(zhuǎn)類(lèi)對(duì)象的方法示例
這篇文章主要給大家介紹了關(guān)于Java跨域Json字符轉(zhuǎn)類(lèi)對(duì)象的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11
解決Java導(dǎo)入excel大量數(shù)據(jù)出現(xiàn)內(nèi)存溢出的問(wèn)題
今天小編就為大家分享一篇解決Java導(dǎo)入excel大量數(shù)據(jù)出現(xiàn)內(nèi)存溢出的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-06-06
java實(shí)現(xiàn)租車(chē)系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)租車(chē)系統(tǒng),以及遇到的兩個(gè)問(wèn)題解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
springBoot?@Scheduled實(shí)現(xiàn)多個(gè)任務(wù)同時(shí)開(kāi)始執(zhí)行
這篇文章主要介紹了springBoot?@Scheduled實(shí)現(xiàn)多個(gè)任務(wù)同時(shí)開(kāi)始執(zhí)行,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12

