ProcessRuntimeEventListener
activiti7中,提供了ProcessRuntimeEventListener
監(jiān)聽器,用于監(jiān)聽流程實(shí)例的結(jié)束事件
/**
* 流程完成監(jiān)聽器
*/
@Slf4j
@Component
public class ProcessCompleteListener implements ProcessRuntimeEventListener<ProcessCompletedEvent> {
@Override
public void onEvent(ProcessCompletedEvent event) {
// ...處理自己的業(yè)務(wù)邏輯
// 這里寫一段拋出異常的測(cè)試代碼
int a = 1 / 0;
}
}
上述代碼中,由于1/0會(huì)拋出運(yùn)行時(shí)異常,理論上來說應(yīng)該被我們的全局異常所捕獲
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 通用未知異常
*/
@ExceptionHandler(Throwable.class)
@ResponseStatus(HttpStatus.OK)
public ResultEntity<?> error(Exception e) {
return ResultEntity.fail(ResultEnum.SERVER_ERROR, "系統(tǒng)錯(cuò)誤,請(qǐng)聯(lián)系管理員!");
}
}
實(shí)際情況是無法捕獲
解決思路
既然異常沒有被一層一層的拋出去直到被全局異常捕獲,那說明調(diào)用ProcessCompleteListener.onEvent()
的某個(gè)地方使用try catch
將異常捕獲了該異常并沒有繼續(xù)向上拋出,隨著這個(gè)思路,我們將斷點(diǎn)打在1/0這行代碼上面
然后重新運(yùn)行代碼,讓代碼執(zhí)行到斷點(diǎn)位置
然后在左側(cè)的方法調(diào)用棧中,一個(gè)一個(gè)找,是哪個(gè)地方調(diào)用了onEvent并且進(jìn)行了try catch異常捕捉
找到使用了try catch的實(shí)際的調(diào)用處,如圖所示
catch中通過判斷l(xiāng)istener的isFailOnException()
來控制是否拋出異常
由斷點(diǎn)可以看出,listener對(duì)象是ProcessCompletedListenerDelegate
由此可見isFailOnException
總是返回false,所以一直不會(huì)將異常拋出
解決辦法
我們可以創(chuàng)建一個(gè)CustomProcessCompletedListenerDelegate
自定義子類繼承該類,然后重新isFailOnException
方法,但是問題是如何將spring環(huán)境中的ProcessCompletedListenerDelegate
替換成我們的自定義子類
那么我們就看ProcessCompletedListenerDelegate
類是什么時(shí)候創(chuàng)建出來的,在創(chuàng)建時(shí),替換成我們自定義的類
有2個(gè)辦法:
- 給
ProcessCompletedListenerDelegate
類的構(gòu)造器上面打斷點(diǎn)(小提示:如果遇到想給構(gòu)造器打斷點(diǎn),但是沒有寫構(gòu)造器的情況下,就在類名所在行打斷點(diǎn)),然后重啟項(xiàng)目,等執(zhí)行到斷點(diǎn)行的時(shí)候,再次查看方法調(diào)用棧,找到什么時(shí)候創(chuàng)建的該類 - 直接alt + F7,或者右鍵類名點(diǎn)
Find Usages
查找使用地方
取巧一點(diǎn)的方法是先用方式2,看看使用的地方多不多,如果很多無法確定具體使用的地方,那么在用方法1
這里可以直接使用方法2,找到調(diào)用處
ProcessRunTimeAutoConfiguration的369行在使用,直接點(diǎn)進(jìn)去
文章來源:http://www.zghlxwxcb.cn/news/detail-740629.html
這就好辦了,看到了@ConditionOnMissingBean
,那么我們可以直接自己注入CustomProcessCompletedListenerDelegate
到Spring中來管理就可以文章來源地址http://www.zghlxwxcb.cn/news/detail-740629.html
解決代碼如下
自定義監(jiān)聽器委托類CustomProcessCompletedListenerDelegate
/**
* 繼承ProcessCompletedListenerDelegate,重寫isFailOnException以達(dá)目的
*/
public class CustomProcessCompletedListenerDelegate extends ProcessCompletedListenerDelegate {
public CustomProcessCompletedListenerDelegate(List<ProcessRuntimeEventListener<ProcessCompletedEvent>> processRuntimeEventListeners, ToProcessCompletedConverter processCompletedConverter) {
super(processRuntimeEventListeners, processCompletedConverter);
}
@Override
public boolean isFailOnException() {
return true;
}
}
注入Spring,我這里使用的是SpringBoot
@Configuration
// 如果是spi方式注入,則添加如下這行控制順序
// @AutoConfigureBefore(ProcessRuntimeAutoConfiguration.class)
public class ProcessCompleteListenerConfig {
@Bean("registerProcessCompletedListenerDelegate")
public InitializingBean registerProcessCompletedListenerDelegate(
RuntimeService runtimeService,
@Autowired(required = false) List<ProcessRuntimeEventListener<ProcessCompletedEvent>> eventListeners,
ToProcessCompletedConverter converter) {
return () -> runtimeService.addEventListener(new CustomProcessCompletedListenerDelegate(getInitializedListeners(eventListeners),
converter),
ActivitiEventType.PROCESS_COMPLETED);
}
private <T> List<T> getInitializedListeners(List<T> eventListeners) {
return eventListeners != null ? eventListeners : Collections.emptyList();
}
}
到了這里,關(guān)于Activiti7流程結(jié)束監(jiān)聽事件中,拋出的異常無法被spring全局異常捕捉的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!