问题
I have the spring mvc application. To catch exceptions I use @ExceptionHandler
annotation.
@ControllerAdvise
public class ExceptionHandlerController {
@ExceptionHandler(CustomGenericException.class)
public ModelAndView handleCustomException(CustomGenericException ex) {
....
}
}
But I think that I will catch only exceptions after controller methods invocations.
But how to catch exceptions generated outside the rest context? For example lifecycle callbacks or scheduled tasks.
回答1:
But how to catch exceptions generated outside the rest context? For example lifecycle callbacks or scheduled tasks
One solution that I can think of it, is to use a After Throwing Advice. The basic idea is to define an advice that would caught exceptions thrown by some beans and handle them appropriately.
For example, you could define a custom annotation like:
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Handled {}
And use that annotation to mark methods that should be advised. Then you can annotate your, say, jobs with this annotation:
@Component
public class SomeJob {
@Handled
@Scheduled(fixedRate = 5000)
public void doSomething() {
if (Math.random() < 0.5)
throw new RuntimeException();
System.out.println("I escaped!");
}
}
And finally define an advice that handles exceptions thrown by methods annotated with @Handled
:
@Aspect
@Component
public class ExceptionHandlerAspect {
@Pointcut("@annotation(com.so.Handled)")
public void handledMethods() {}
@AfterThrowing(pointcut = "handledMethods()", throwing = "ex")
public void handleTheException(Exception ex) {
// Do something useful
ex.printStackTrace();
}
}
For more finer grain control over method executions, you could use Around Advice, too. Also don't forget to enable autoproxy-ing, using @EnableAspectJAutoProxy
on a Java config or <aop:aspectj-autoproxy/>
in XML configurations.
来源:https://stackoverflow.com/questions/37164855/where-can-i-catch-non-rest-controller-exceptions-in-spring