博主
258
258
258
258
专辑

学习笔记20230918

亮子 2023-09-18 02:57:38 3492 0 0 0

1、添加依赖

如果是springboot项目,则不需要添加

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>

2、自定义注解

package com.bw.pxx.user.anno;

import java.lang.annotation.*;

/**
 * @author 军哥
 * @version 1.0
 * @description: PxxLog
 * @date 2023/9/18 9:47
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface PxxLog {
    String value() default "pxx";
    String level() default "info";
    String roles() default "";
}

3、定义切面类

package com.bw.pxx.user.aop;

import com.alibaba.fastjson.JSON;
import com.bw.pxx.comm.vo.user.LoginVo;
import com.bw.pxx.user.anno.PxxLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;

/**
 * @author 军哥
 * @version 1.0
 * @description: PxxLogAspect
 * @date 2023/9/18 9:52
 */

@Component
@Aspect
public class PxxLogAspect {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    /**
     * @description 根据注解来进行切点
     * @author 军哥
     * @date 2023/9/18 9:54
     * @version 1.0
     */
    @Pointcut("@annotation(com.bw.pxx.user.anno.PxxLog)")
    public void pxxLogPointCut() {}

    @Before(value = "pxxLogPointCut()")
    public void doBeforeRole(JoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        // 获取方法名
        String methodName = signature.getName();
        // 获取参数
        List<Object> args = Arrays.asList(point.getArgs());

        Method method = signature.getMethod();
        PxxLog annotation = method.getAnnotation(PxxLog.class);
        System.out.println("前置通知(注解) => value:"+annotation.value());
        System.out.println("前置通知(注解) => level:"+annotation.level());
        System.out.println("前置通知(注解:权限) => roles:"+annotation.roles());

        // 获取参数
        Object o = args.get(0);
        LoginVo loginVo = (LoginVo)o;

        // zhangsan
        String key = loginVo.getUsername();
        // user,seller
//        String roles = (String)stringRedisTemplate.opsForValue().get(key);
        String roles = "user,seller";
        if(!roles.contains(annotation.roles())) {
            System.out.println("前置通知:没有权限");
            throw new RuntimeException("没有权限");
        }

        System.out.println("前置通知 => 方法为:" + methodName + ",参数为:" + JSON.toJSONString(args));

    }

    @AfterReturning(value = "pxxLogPointCut()", returning = "returnValue")
    public void doAfterReturning(JoinPoint point, Object returnValue){

        MethodSignature signature = (MethodSignature) point.getSignature();
        // 获取方法名
        String methodName = signature.getName();
        // 获取参数
        List<Object> args = Arrays.asList(point.getArgs());

        Method method = signature.getMethod();
        PxxLog annotation = method.getAnnotation(PxxLog.class);
        System.out.println("后置通知(注解) => value:"+annotation.value());
        System.out.println("后置通知(注解) => level:"+annotation.level());

        System.out.println("后置通知 => 方法为:" + methodName + ",参数为:" + JSON.toJSONString(args) + ",返回值为:" + JSON.toJSONString(returnValue));
    }

    @Before(value = "execution(* com.bw.pxx.user.controller.TbAdminController.sendCode(..))")
    public void doBefore(JoinPoint point) throws Exception {
        MethodSignature signature = (MethodSignature) point.getSignature();

        // 获取注解信息
        Method method = signature.getMethod();
        System.out.println("前置通知:"+method.getName());

        List<Object> args = Arrays.asList(point.getArgs());
        System.out.println("前置通知:"+JSON.toJSONString(args));


//        Method method = signature.getMethod();
//        SmLog annotation = method.getAnnotation(SmLog.class);
//        System.out.println("前置通知 => value:"+annotation.value());
//        System.out.println("前置通知 => level:"+annotation.level());
//
//        // 检查权限
//        if(!annotation.value().equals("insert")) {
//            throw new Exception("权限不足");
//        }
//        System.out.println("前置通知 => 权限合法");
    }
}

4、全局异常拦截

package com.bw.pxx.user.filter;

import com.bw.pxx.comm.domain.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * @author 军哥
 * @version 1.0
 * @description: GlobalExceptionHandler
 * @date 2023/9/18 10:48
 */

@RestControllerAdvice
public class GlobalExceptionHandler {

    //空指针异常
    @ExceptionHandler(value = RuntimeException.class)
    public Result nullPointerExceptionHandler(RuntimeException ex) {
        ex.printStackTrace();

        return Result.FAILED(500, "服务器内部错误");
    }
}