1000字范文,内容丰富有趣,学习的好帮手!
1000字范文 > 自定义注解捕获异常

自定义注解捕获异常

时间:2020-08-12 01:32:58

相关推荐

自定义注解捕获异常

1. 自定义注解

/*** 服务异常捕捉**/@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)public @interface ServiceExceptionCatch {/*** 分钟/频率*/int THREE = 3;/*** 通知员工id,如果有多个请用英文,分开** @return*/String notifyEmpId() default "123456";/*** 通知时间(分钟), 在notifyTime(时间内)通知了notifyFrequency(次数)后 则不在通知** @return*/int notifyTime() default THREE;/*** 通知频率** @return*/int notifyFrequency() default THREE;}

方式一

@RestControllerAdvice都是对Controller进行增强的,可以全局捕获spring mvc抛的异常。

@ExceptionHandler之后,当一个Controller中有方法加了,这个Controller其他方法中没有捕获的异常就会以参数的形式传入加了@ExceptionHandler注解的那个方法中。

@Slf4j@RestControllerAdvicepublic class AppExceptionHandler {/*** 自定义异常** @param e /* @return /*/@ExceptionHandler(value = CenterException.class)public HttpResult<String> captureException(CenterException e) {log.error("出现业务异常:", e);return HttpResult.error(e.getErrorCode(), e.getMessage());}}

方式二定义AOP,使用@AfterThrowing (异常通知)

@Aspect@Component@Slf4jpublic class ServiceExceptionCatchAspect {@Resourceprivate DingMsgUtil dingMsgUtil;@Resourceprivate RedisTemplate redisTemplate;/*** 定义切点*/@Pointcut("@annotation(com.sec.appcenter.aop.ServiceExceptionCatch)")private void servicePointCut() {}@AfterThrowing(throwing = "error", pointcut = "servicePointCut()")public void afterThrowingAdvice(JoinPoint pjp, Throwable error) {try {String name = pjp.getSignature().getName();log.info(name + "异常:" + "\t" + error.getMessage());MethodSignature methodSignature = (MethodSignature) pjp.getSignature();Method targetMethod = methodSignature.getMethod();ServiceExceptionCatch serviceExceptionCatch = targetMethod.getAnnotation(ServiceExceptionCatch.class);HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();String path = request.getServletPath();//判断通知频率if (!notifyFrequency(serviceExceptionCatch, path, User)) {log.info("频率超出,不执行,user:{},serviceExceptionCatch:{}", User.getId(), JSON.toJSONString(serviceExceptionCatch));return;}// 记录下请求内容log.info("URL : " + request.getRequestURL().toString());log.info("PATH : " + path);Map<String, Object> map = new TreeMap<>();map.put("异常信息 :", error.getMessage());map.put("URL :", request.getRequestURL().toString());map.put("PATH :", path);map.put("时间 :", DateUtil.parse2StringDatetime(new Date()));dingMsgUtil.sendFormDingMsg("异常通知", map, Arrays.asList(serviceExceptionCatch.notifyEmpId().split(",")), request.getRequestURL().toString());} catch (Exception e) {log.error("同步异常至开发失败:", e);}}/*** 判断通知频率** @param serviceExceptionCatch* @return*/private boolean notifyFrequency(ServiceExceptionCatch serviceExceptionCatch, String path, UserData User) {String empId = User.getId();String redisKey = empId + path;Long increment = redisTemplate.opsForValue().increment(redisKey, 1);if (increment == 1) {//设置有效期redisTemplate.expire(redisKey, serviceExceptionCatch.notifyTime(), TimeUnit.MINUTES);}if (increment > serviceExceptionCatch.notifyFrequency()) {log.info("通知频率超出,不通知到开发");return false;}return true;}}

3. 常见问题

1. 自定义注解不生效

建议检查一下方法是否为public, 具体原因,看到一篇不错的回答听说SpringAOP 有坑?那就来踩一踩 - 掘金设置一下动态代理使用cglib

在主启动类/调用的类上 加上

@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)

具体自己去挖

2. 使用内部调用,捕获不到异常,再开一篇

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。