如何在 Spring Boot 中捕获非 MVC 和非 REST 异常
How to catch non-MVC and non-REST exceptions in Spring Boot
我已经找到了无数关于如何在 Spring MVC 或 Spring REST 中捕获未处理异常的教程,但我想知道的是如何捕获未处理异常根本不使用 Spring Web 框架。
我正在编写一个没有 Web 组件的应用程序,我不会导入 Spring Web 仅用于异常处理。
当 @Service
抛出未处理的异常时,我需要捕获它以便将其正确记录到 Raygun。
例如,在故意抛出未捕获异常的服务中考虑此方法:
@Scheduled(fixedDelay = 100)
public void doSomething() {
throw new RuntimeException("Uh oh!");
}
它的输出将是:
2017-08-16 00:19:40.202 ERROR 91168 --- [pool-1-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task.
java.lang.RuntimeException: Uh oh!
at com.mitchtalmadge.example.ExampleService.doSomething(ClassSyncService.java:48) ~[classes/:na]
at com.mitchtalmadge.example.ExampleService$$FastClassBySpringCGLIB$dd464d8.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
...
我如何捕捉到它?
没有简单的方法吗?
您可以使用spirngframework中的aop,首先您应该配置aop配置。
<bean id="aspect" class="com.zhuyiren.Main"/>
<aop:config>
<aop:aspect ref="aspect">
<aop:after-throwing method="after" throwing="ex" pointcut="execution(* com.zhuyiren.service..*.*(..)),args(ex)"/>
</aop:aspect>
</aop:config>
然后你应该声明一个 aspect
class 方法被命名为 after
:
public class Main {
public void after(JoinPoint point,Throwable ex){
System.out.println(point);
System.out.println("catch error:"+ex.getMessage());
}
当服务抛出错误时,该方法将捕获并解决它。
在我的服务中,我创建了一个 ArithmeticException,并且 运行 应用程序打印为:
execution(TeacherInfo com.zhuyiren.service.TeacherService.getTeacherInfo())
catch error:/ by zero
当然,上面的配置是依赖于xml,你也可以通过Annotation
来完成,比如@Aspect
,@Pointcut
,@AfterThrowing
.
您可以定义一个方面。
使用基于 Java 的配置,它将如下所示:
@Aspect
public class ExceptionHandler {
@AfterThrowing(pointcut="execution(* your.base.package..*.*(..))", throwing="ex")
public void handleError(Exception ex) {
//handling the exception
}
}
如果需要注入bean,添加@Component
注解:
@Aspect
@Component
public class ExceptionHandler {
@Autowired
private NotificationService notificationService;
@AfterThrowing(pointcut="execution(* your.base.package..*.*(..))", throwing="ex")
public void handleError(Exception ex) {
notificationService.sendMessage(ex.getMessage());
}
}
我已经找到了无数关于如何在 Spring MVC 或 Spring REST 中捕获未处理异常的教程,但我想知道的是如何捕获未处理异常根本不使用 Spring Web 框架。
我正在编写一个没有 Web 组件的应用程序,我不会导入 Spring Web 仅用于异常处理。
当 @Service
抛出未处理的异常时,我需要捕获它以便将其正确记录到 Raygun。
例如,在故意抛出未捕获异常的服务中考虑此方法:
@Scheduled(fixedDelay = 100)
public void doSomething() {
throw new RuntimeException("Uh oh!");
}
它的输出将是:
2017-08-16 00:19:40.202 ERROR 91168 --- [pool-1-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler : Unexpected error occurred in scheduled task.
java.lang.RuntimeException: Uh oh!
at com.mitchtalmadge.example.ExampleService.doSomething(ClassSyncService.java:48) ~[classes/:na]
at com.mitchtalmadge.example.ExampleService$$FastClassBySpringCGLIB$dd464d8.invoke(<generated>) ~[classes/:na]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:669)
...
我如何捕捉到它?
没有简单的方法吗?
您可以使用spirngframework中的aop,首先您应该配置aop配置。
<bean id="aspect" class="com.zhuyiren.Main"/>
<aop:config>
<aop:aspect ref="aspect">
<aop:after-throwing method="after" throwing="ex" pointcut="execution(* com.zhuyiren.service..*.*(..)),args(ex)"/>
</aop:aspect>
</aop:config>
然后你应该声明一个 aspect
class 方法被命名为 after
:
public class Main {
public void after(JoinPoint point,Throwable ex){
System.out.println(point);
System.out.println("catch error:"+ex.getMessage());
}
当服务抛出错误时,该方法将捕获并解决它。 在我的服务中,我创建了一个 ArithmeticException,并且 运行 应用程序打印为:
execution(TeacherInfo com.zhuyiren.service.TeacherService.getTeacherInfo())
catch error:/ by zero
当然,上面的配置是依赖于xml,你也可以通过Annotation
来完成,比如@Aspect
,@Pointcut
,@AfterThrowing
.
您可以定义一个方面。 使用基于 Java 的配置,它将如下所示:
@Aspect
public class ExceptionHandler {
@AfterThrowing(pointcut="execution(* your.base.package..*.*(..))", throwing="ex")
public void handleError(Exception ex) {
//handling the exception
}
}
如果需要注入bean,添加@Component
注解:
@Aspect
@Component
public class ExceptionHandler {
@Autowired
private NotificationService notificationService;
@AfterThrowing(pointcut="execution(* your.base.package..*.*(..))", throwing="ex")
public void handleError(Exception ex) {
notificationService.sendMessage(ex.getMessage());
}
}