ProcessRuntimeEventListener
activiti7中,提供了ProcessRuntimeEventListener
监听器,用于监听流程实例的结束事件
/**
* 流程完成监听器
*/
@Slf4j
@Component
public class ProcessCompleteListener implements ProcessRuntimeEventListener<ProcessCompletedEvent> {
@Override
public void onEvent(ProcessCompletedEvent event) {
// ...处理自己的业务逻辑
// 这里写一段抛出异常的测试代码
int a = 1 / 0;
}
}
上述代码中,由于1/0会抛出运行时异常,理论上来说应该被我们的全局异常所捕获
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
/**
* 通用未知异常
*/
@ExceptionHandler(Throwable.class)
@ResponseStatus(HttpStatus.OK)
public ResultEntity<?> error(Exception e) {
return ResultEntity.fail(ResultEnum.SERVER_ERROR, "系统错误,请联系管理员!");
}
}
实际情况是无法捕获
解决思路
既然异常没有被一层一层的抛出去直到被全局异常捕获,那说明调用ProcessCompleteListener.onEvent()
的某个地方使用try catch
将异常捕获了该异常并没有继续向上抛出,随着这个思路,我们将断点打在1/0这行代码上面
然后重新运行代码,让代码执行到断点位置
然后在左侧的方法调用栈中,一个一个找,是哪个地方调用了onEvent并且进行了try catch异常捕捉
找到使用了try catch的实际的调用处,如图所示
catch中通过判断listener的isFailOnException()
来控制是否抛出异常
由断点可以看出,listener对象是ProcessCompletedListenerDelegate
由此可见isFailOnException
总是返回false,所以一直不会将异常抛出
解决办法
我们可以创建一个CustomProcessCompletedListenerDelegate
自定义子类继承该类,然后重新isFailOnException
方法,但是问题是如何将spring环境中的ProcessCompletedListenerDelegate
替换成我们的自定义子类
那么我们就看ProcessCompletedListenerDelegate
类是什么时候创建出来的,在创建时,替换成我们自定义的类
有2个办法:
- 给
ProcessCompletedListenerDelegate
类的构造器上面打断点(小提示:如果遇到想给构造器打断点,但是没有写构造器的情况下,就在类名所在行打断点),然后重启项目,等执行到断点行的时候,再次查看方法调用栈,找到什么时候创建的该类 - 直接alt + F7,或者右键类名点
Find Usages
查找使用地方
取巧一点的方法是先用方式2,看看使用的地方多不多,如果很多无法确定具体使用的地方,那么在用方法1
这里可以直接使用方法2,找到调用处
ProcessRunTimeAutoConfiguration的369行在使用,直接点进去
文章来源:https://www.toymoban.com/news/detail-740629.html
这就好办了,看到了@ConditionOnMissingBean
,那么我们可以直接自己注入CustomProcessCompletedListenerDelegate
到Spring中来管理就可以文章来源地址https://www.toymoban.com/news/detail-740629.html
解决代码如下
自定义监听器委托类CustomProcessCompletedListenerDelegate
/**
* 继承ProcessCompletedListenerDelegate,重写isFailOnException以达目的
*/
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();
}
}
到了这里,关于Activiti7流程结束监听事件中,抛出的异常无法被spring全局异常捕捉的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!