SpringAOP手写全局异常处理

32 篇文章 1 订阅
19 篇文章 3 订阅

1、使用@AfterThrowing异常通知:

注:使用异常通知,不会完全处理异常,异常会向上继续传递给调用者。

1.1自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ProcessException {
	Class<? extends Throwable>[] value() default {};
}

1.2编写切面

@Component
@Aspect
public class UserAspect {
        @Pointcut("@within(org.springframework.stereotype.Controller)")
	private void exceptionProcesser() {}
    	@AfterThrowing(value = "exceptionProcesser()", throwing = "e")
	public void afterThrowingMethod(JoinPoint point, Throwable e) {
		Class<?> clazz = point.getTarget().getClass();
		Method[] methods = clazz.getMethods();
		for (Method m : methods) {
			ProcessException anno = m.getAnnotation(ProcessException.class);
			if (anno != null) {
				Class<? extends Throwable>[] exArr = anno.value();
				if (exArr.length == 0) {
					if (e instanceof RuntimeException) {
						try {
							m.invoke(clazz.newInstance(), e);
						} catch(Exception ex) {
							e.printStackTrace();
						}
					}
				} else {
					for (Class<? extends Throwable> exClass : exArr) {
						if (exClass.isInstance(e)) {
							try {
								m.invoke(clazz.newInstance(), e);
							} catch(Exception ex) {
								e.printStackTrace();
							}
						}
					}
				}
				break;
			}
		}
	}
}

1.3写全局异常处理方法:

public abstract class BaseController {
    @ProcessException(ServiceException.class)
    public ResponseResult<Void> handleException(Throwable e) {
    	System.out.println(e.getMessage());
        ResponseResult<Void> result = new ResponseResult<>();
        result.setMessage(e.getMessage());
        if (e instanceof UsernameDuplicateKeyException) {
            result.setState(4001);
        } else if (e instanceof InsertException) {
            result.setState(4002);
        } else if (e instanceof UserNotFoundException) {
            result.setState(4003);
        } else if (e instanceof PasswordNotMatchException) {
            result.setState(4004);
        } else if (e instanceof UpdateException) {
            result.setState(4005);
        }
        return result;
    }
}
@Controller
@RequestMapping("/users")
public class UserController extends BaseController {
	
	@Autowired
	private IUserService userService;
	
	@PostMapping("/login")
	@ResponseBody
	public ResponseResult<Void> login(String username, String password, HttpSession session) {
		User user = userService.login(username, password);
		session.setAttribute("uid", user.getUid());
              session.setAttribute("username", user.getUsername());
		return new ResponseResult<>(SUCCESS);
	} 
	
}
@Data
public class ResponseResult<T> implements Serializable {
    private static final long serialVersionUID = 8011176026667744133L;

    private Integer state;
    private String message;
    private T data;

    public ResponseResult() {
    }

    public ResponseResult(Integer state) {
        this.state = state;
    }
    public ResponseResult(Integer state, T data) {
        this.state = state;
        this.data = data;
    }
}

2、使用Around环绕通知:

1.1自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface ProcessException {
	Class<? extends Throwable>[] value() default {};
}

1.2编写切面

@Component
@Aspect
public class UserAspect {
        @Pointcut("@within(org.springframework.stereotype.Controller)")
	private void exceptionProcesser() {}
        @Around(value="exceptionProcesser()")
	public Object around(ProceedingJoinPoint jp) throws Throwable {
		try {
			return jp.proceed();
		} catch (Throwable e) {
			try {
				Class<?> clazz = jp.getTarget().getClass();
				Method[] methods = clazz.getMethods();
				for (Method m : methods) {
					ProcessException anno = m.getAnnotation(ProcessException.class);
					if (anno != null) {
						Class<? extends Throwable>[] exArr = anno.value();
						if (exArr.length == 0) {
							if (e instanceof RuntimeException) {
								return m.invoke(clazz.newInstance(), e);
							}
						} else {
							for (Class<? extends Throwable> exClass : exArr) {
								if (exClass.isInstance(e)) {
									return m.invoke(clazz.newInstance(), e);
								}
							}
						}
					}
				}
				throw e;
			} catch (Exception ex) {
				throw ex;
			}
		}
	}
}

1.3写全局异常处理方法:

public abstract class BaseController {
    @ProcessException(ServiceException.class)
    public ResponseResult<Void> handleException(Throwable e) {
    	System.out.println(e.getMessage());
        ResponseResult<Void> result = new ResponseResult<>();
        result.setMessage(e.getMessage());
        if (e instanceof UsernameDuplicateKeyException) {
            result.setState(4001);
        } else if (e instanceof InsertException) {
            result.setState(4002);
        } else if (e instanceof UserNotFoundException) {
            result.setState(4003);
        } else if (e instanceof PasswordNotMatchException) {
            result.setState(4004);
        } else if (e instanceof UpdateException) {
            result.setState(4005);
        }
        return result;
    }
}
@Controller
@RequestMapping("/users")
public class UserController extends BaseController {
	
	@Autowired
	private IUserService userService;
	
	@PostMapping("/login")
	@ResponseBody
	public ResponseResult<Void> login(String username, String password, HttpSession session) {
		User user = userService.login(username, password);
		session.setAttribute("uid", user.getUid());
              session.setAttribute("username", user.getUsername());
		return new ResponseResult<>(SUCCESS);
	} 
	
}
@Data
public class ResponseResult<T> implements Serializable {
    private static final long serialVersionUID = 8011176026667744133L;

    private Integer state;
    private String message;
    private T data;

    public ResponseResult() {
    }

    public ResponseResult(Integer state) {
        this.state = state;
    }
    public ResponseResult(Integer state, T data) {
        this.state = state;
        this.data = data;
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值