Как поймать исключения не MVC и не REST в Spring Boot

Мне удалось найти бесконечное количество учебных пособий о том, как перехватывать необработанные исключения в Spring MVC или Spring REST, но я хочу знать, как перехватывать необработанные исключения, вообще не используя инфраструктуру Spring 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$$1dd464d8.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)
    ...

Как мне это поймать?

Нет ли простого способа сделать это?

2 ответа

Решение

Вы можете использовать aop в spirngframework, сначала вы должны настроить конфигурацию 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 у класса есть метод 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
     }
}

Если вам нужно внедрить компонент, добавьте аннотацию @Component:

@Component
@Aspect
public class ExceptionHandler {

    @Autowired
    private SomeService someService;

    @AfterThrowing(pointcut="execution(* your.base.package..*.*(..))", throwing="ex")
    public void handleError(Exception ex) {
        someService.handleError(ex);
     }
}
Другие вопросы по тегам