由于项目中有的地方会出现异常,当出现次数多了之后,手写try-catch感觉十分的麻烦,于是查阅资料发现可以使用SpringBoot中的@ControllerAdivce注解来处理异常,并通过AOP的方式记录错误日志。
org.springframework.boot
spring-boot-starter-aop
1、ControllerAdvice
@org.springframework.web.bind.annotation.ControllerAdvice
@ResponseBody
public class ControllerAdvice {
@ExceptionHandler(MyException.class)
public String MyExceptionHandler(MyException e){
return "MyException has occurred";
}
@ExceptionHandler(Exception.class)
public String ExceptionHandler(Exception e){
return "server error";
}
}
全局异常捕获。这里只能处理Controller层抛出的异常,如果异常在Controller层抛出之前被捕获,则不会到达这里。
2、自定义注解Log
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Log {
}
自定义注解,用于标注需要记录错误日志的方法。
3、ExceptionAOP
@Aspect
@Component//将此类加入Spring容器中
public class ExceptionAop {
@Pointcut("@annotation(com.lqf.springboottest.annotation.Log)")//以自定义注解Log为切面
public void pointCut(){
}
// @Before("pointCut()")//由于只是做日志记录,所以before和after并没有使用
// public void before(JoinPoint point){
// System.out.println("this is ExceptionAop before");
// }
//
// @After("pointCut()")
// public void after(JoinPoint point){
// System.out.println("this is ExceptionAop after");
// }
@AfterThrowing(value = "pointCut()",throwing = "e")
public void afterThrowing(JoinPoint point, Exception e) throws IllegalAccessException {
System.out.println("this is ExceptionAop afterThrowing");
LoggerFactory.getLogger(point.getTarget().getClass()).error(e.getMessage());
}
}
记录出现异常的地方以及异常信息。
4、MyService
@Component
public class MyService {
@Log
public void throwing() throws MyException {
System.out.println("this is service throwing");
throw new MyException("throwing MyException");
}
}
5、测试类
@Test
public void testService(){
try {
myService.throwing();
} catch (MyException e) {
System.out.println("catch");
}
}
输出如下
this is service throwing
this is ExceptionAop afterThrowing
2019-05-11 23:50:55.421 ERROR 9376 --- [ main] c.lqf.springboottest.service.MyService : throwing MyException
catch
异常在项目中经常出现,如果出现的异常处理后的结果仍然是终止方法,则可以使用全局处理的办法统一处理,可以少些很多try-catch,并通过自定义注解以及AOP的方式来记录异常日志,使得开发又简便了一些。
不过这个方法只有在方法往上抛的情况才能通过切面记录错误日志,否则是获取不到错误信息的。