问题场景:
在项目开发中,出现的一些异常是可以预见的
最简单的做法就是使用try catch去处理这些异常
问题 业务代码太多的try catch使得代码不简洁,可读性变差
问题思考:
那么有没有一种方法,可以把这些异常进行统一处理以及日志输出呢?答案是有的。
自定义注解 + AOP + AbstractErrorController
分部说明:
1、首先我们定义一个自定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
//注解使用的位置
String location();
//使用的相关信息
String msg() default "";
}
2、接着去编写aop切面
@Aspect
@Component
public class MyAop {
//这里注解的路径不能错
@Pointcut("@annotation(com.study.practice.aop4Exception.MyAnnotation)")
public void access(){
}
@AfterThrowing(pointcut = "access()",throwing = "e")
public void afterThrowing(Exception e){
System.out.println("something wrong");
}
}
3、在方法上使用注解
@Service
public class TestService {
@MyAnnotation(msg = "试一试",location = "testService")
public void myTest(){
System.out.println("myTest");
int i = 1/0;
}
}
4、在controller调用这个service (略)
注意:
好像必须启动项目aop才能生效,这可能和注解的runtime时生效有关,但我用springboot test直接测试是不行的
访问接口
可以看出,成功进入异常处理,但仍然有异常抛出,这是因为aop并不能完全处理异常,异常仍会向上层调用者抛出。
问题不大,我们继续改善他
5、编写异常的处理类
@RestController
@ControllerAdvice
public class GlobalExceptionHandler extends AbstractErrorController {
public GlobalExceptionHandler(ErrorAttributes errorAttributes) {
super(errorAttributes);
}
@Override
public String getErrorPath() {
return null;
}
@ExceptionHandler(Exception.class) //制定你要用这个方法处理什么类型的异常
public String handle(Exception e){
System.out.println(e.getMessage());
return "服务器错误";
}
}
这样就可以在返回对前端友好数据的同时,记录异常情况并且处理,比如发生异常后发送邮件,消息通知开发,运维人员
补充 如何获取注解中的参数
@Aspect
@Component
public class MyAop {
@Pointcut("@annotation(com.study.practice.aop4Exception.MyAnnotation)")
public void access(){
}
@AfterThrowing(pointcut = "access()",throwing = "e")
public void afterThrowing(JoinPoint joinPoint,Exception e){
MethodSignature signature =(MethodSignature) joinPoint.getSignature();
MyAnnotation myAnnotation = signature.getMethod().getAnnotation(MyAnnotation.class);
String location = myAnnotation.location();
String msg = myAnnotation.msg();
System.out.println("location:" + location + " ,msg:" + msg);
System.out.println("something wrong");
}
}
获取成功,掌握到这里,我们已经可以实现很多东西了,具体各位可以根据各自业务进行拓展。