Springboot @Aspect

需求:

  • 给某些特定的api 打统一规范的log
  • 对某些固定的api 做权限校验

进程:

  • 权限校验和统一的log 这只有两件事情,如果要在每个api 前面带上校验后面带上log那不改到天都黑了
  • 使用 @Aspect 这个注解叫切面,他可以在api 请求的前后做一些额外的事情
  • 首先加上aop 的依赖
    <artifactId>spring-boot-starter-aop</artifactId>
  • 创建一个类标记为 @Aspect
    @Aspect
    @Component
    public class LogAspect{
    
    }
  • 标记这个类是为了哪些api  在方法上加上@Pointcut 做拦截处理
    // excution 模式
    //表示public 的返回类型为所有类型的 方法在com.controller 包下的所有子包,下的所有方法名,任意参数单api
    // 第一个 * 表示所有返回类型, controller 后的 .. 表示所有的子包,后面的 * 表示所有的类,.* 表示所有的方法, (..) 表示任意的参数
    
    @Pointcut("execution(public * com.controller..*.*(..))")
    private void webLog() {
    }
    
    
    //annotation 模式
    //表示针对有 ApiToken 注解的方法使用这个切面
    @Pointcut("@annotation(common.annotation.ApiToken)")
    private void webLog() {
    }
  •  使用 @Around 通过切面开始对api 做统一log
    @Around("webLog()")
    public Object permissionCheck(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("start");
    // 获取当前请求对象
        ServletRequestAttributes attributes = (ServletRequestAttributes)     RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
    
    
    for (Object object : joinPoint.getArgs()) {
        if (object instanceof TokenAuthApi) {
             TokenAuthApi api = (TokenAuthApi) object;
             appKey = api.getAppKey();
             // 设置body的参数,供统一异常处理时获取
             request.setAttribute("appKey", appKey);
         }
    }
    
    // proceed  表示开始执行原本需要执行的进程,返回的result 是原本应该会返回到前端的数据,proceed 也可以传入参数,传入的参数会完全替换掉之前的参数,要谨慎使用
        Object result = joinPoint.proceed();
        log.info("end");
    // 这边必须要做一个返回,甚至这边可以对result 做一个删减处理,但是不建议在这边对处理做处理
        return result;
    }
  •  如果只是期望在切面方法之前调用可以使用 @Before,在之后可以使用@After,不过我觉得,around就可以满足这两个注解的使用,如果是在切面的时候抛出异常可以用@AfterThrowing,在返回之后可以用 @AfterReturning,来捕获方法所有都完成之后的返回值这个方法会多一个参数
    @AfterReturning(pointcut = "webLog()", returning = "result")
        public void doAfterReturning(JoinPoint joinPoint, Object result) {
    
            Signature signature = joinPoint.getSignature();
            String classMethod = signature.getName();
            log.info("方法{}执行完毕,返回参数为:{}", classMethod, result);
        }
    
    
    @AfterThrowing(pointcut = "webLog()", throwing = "ex")
        public void afterThrowing(JoinPoint joinPoint, Throwable ex) {
            Signature signature = joinPoint.getSignature();
            String method = signature.getName();
            // 处理异常的逻辑
            log.info("执行方法{}出错,异常为:{}", method, ex);
        }

 拓展:

  • 除了切面还有过滤器,拦截器,监听器
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值