• Spring 自定义注解 面向切面编程


    Spring 自定义注解

    JDK元注解规范

    @Documented -注解是否将包含在JavaDoc@Retention  -什么时候使用该注解(生命周期)
    	RetentionPolicy.SOURCE: 在变异阶段丢弃,这些注解在编译结束之后就不再有任何意义,所以不会写入到字节码中
    	RetentionPolicy.CLASS: 在类加载的时候丢弃,在字节码文件的处理中有用,注解默认使用方式
    	RetentionPolicy.RUNTIME: 始终不会丢弃,运行器也保留该注解,因此可以使用反射机制读取该注解的信息,自定义注解通常使用这个方式。
    @Target     -注解用于什么地方
    	ElementType.CONSTRUCTOR: 用于描述构造器
    	ElementType.FIELD: 用于描述变量,对象,属性
    	ElementType.LOCAL_VARIABLE: 用于描述局部变量
    	ElementType.METHOD:用于描述方法
    	ElementType.PACKAGE: 用于描述包
    	ElementType.PARAMETER: 用于描述参数
    	ElementType.TYPE: 用于描述类,接口
    @Inherited  -是否允许子类继承该注解
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    1.自定义注解 SayHello

    本 注解用于方法上,入参helloValue默认 5000

    /**
     * @Author Christ @Date 2023/9/6 11:19 @Version 1.0
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface SayHello {
    
      int helloValue() default 5000;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.注解切面
    此处举例四个常用的切面处理
    访问方法前 @Before
    访问方法后 @After
    访问方法拿到了返回值后 @AfterReturning
    抛出异常后 @AfterThrowing

    **
     * @Author Christ @Date 2023/9/6 11:24 @Version 1.0
     */
    @Aspect
    @Component
    public class SayHelloAspect {
    
      /** 定义切点,切点为添加了注解的方法 
    	* com.jlink.common.annotation.SayHello 注解路径
    	*/
      @Pointcut("@annotation(com.christ.common.annotation.SayHello)")
      public void aopPointCut() {}
    
      @Before("aopPointCut()")
      public void beforeHello(JoinPoint point) {
        System.out.println("访问接口前--------------------------");
    
        // 让我看看入参 有没有要验证
        Object[] args = point.getArgs();
        System.out.println(Arrays.toString(args));
    
        // 获取当前方法签名
        MethodSignature signature = (MethodSignature) point.getSignature();
        // 反射机制获取注解
        SayHello sayHello = signature.getMethod().getAnnotation(SayHello.class);
        // 获取注解的值
        int i = sayHello.helloValue();
    
        System.out.println("想要访问我这个接口,那就对我说声hello吧!  注解入参:" + i);
      }
    
      @After("aopPointCut()")
      public void afterHello(JoinPoint point) {
        System.out.println("访问接口后--------------------------");
        // 获取当前方法签名
        MethodSignature signature = (MethodSignature) point.getSignature();
        // 反射机制获取注解
        SayHello sayHello = signature.getMethod().getAnnotation(SayHello.class);
        // 获取注解的值
        int i = sayHello.helloValue();
    
        System.out.println("想要访问我这个接口,那就对我说声hello吧!  注解入参:" + i);
      }
    
      @AfterReturning(pointcut = "aopPointCut()", returning = "jsonResult")
      public void afterHello(JoinPoint point, Object jsonResult) {
        System.out.println("访问接口后拿到了返回值--------------------------");
    
        // 看看返回值拿到了啥
        System.out.println(jsonResult);
    
        // 获取当前方法签名
        MethodSignature signature = (MethodSignature) point.getSignature();
        // 反射机制获取注解
        SayHello sayHello = signature.getMethod().getAnnotation(SayHello.class);
        // 获取注解的值
        int i = sayHello.helloValue();
    
        System.out.println("想要访问我这个接口,那就对我说声hello吧!  注解入参:" + i);
      }
    
      @AfterThrowing(pointcut = "aopPointCut()", throwing = "e")
      public void afterHello(JoinPoint point, Exception e) {
        System.out.println("访问接口后抛出了异常--------------------------");
    
        // 看看返回值拿到了啥
        System.out.println(e);
    
        // 获取当前方法签名
        MethodSignature signature = (MethodSignature) point.getSignature();
        // 反射机制获取注解
        SayHello sayHello = signature.getMethod().getAnnotation(SayHello.class);
        // 获取注解的值
        int i = sayHello.helloValue();
    
        System.out.println("想要访问我这个接口,那就对我说声hello吧!  注解入参:" + i);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    3.使用方法添加SayHello注解
    (无异常情况)

      @PostMapping("/login")
      @SayHello(helloValue = 666) // 注解入参 666
      public Map<String, Object> login(@RequestBody LoginBody loginBody) throws Exception {
        Map<String, Object> ajax = new HashMap<>();
        // 生成令牌
        String token =
            loginService.login(
                loginBody.getUsername(),
                loginBody.getPassword(),
                loginBody.getCode(),
                loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        ajax.put("code", 200);
        ajax.put("msg", "操作成功");
    	//    throw new Exception();
        return ajax;
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    打印日志

    @Before(“aopPointCut()”)
    在这里插入图片描述
    @AfterReturning(pointcut = “aopPointCut()”, returning = “jsonResult”)
    在这里插入图片描述
    @After(“aopPointCut()”)
    在这里插入图片描述

    (有异常情况)

      @PostMapping("/login")
      @SayHello(helloValue = 666) // 注解入参 666
      public Map<String, Object> login(@RequestBody LoginBody loginBody) throws Exception {
        Map<String, Object> ajax = new HashMap<>();
    	throw new Exception();
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    打印日志

    @AfterThrowing(pointcut = “aopPointCut()”, throwing = “e”)
    在这里插入图片描述

  • 相关阅读:
    拥抱下一代前端工具链-Vue老项目迁移Vite探索
    一起来学Kotlin:概念:11. Kotlin this 的使用
    微服务框架 SpringCloud微服务架构 3 Eureka 3.2 Eureka 原理分析
    2022年HNUCM信息科学与工程学院第五届新生赛——正式赛
    大模型 RAG 是什么?
    刷题-买卖股票的最佳时机-C++/java(暴力法,动态规划,单调栈等)
    postgresql源码学习(42)—— 崩溃恢复④ - 日志应用
    为什么要拼命冲刺备考浙大MBA?这可能是最实在的理由了
    银行IT人对转型分布式系统的三大困惑
    2023年软件测试还能不能干,怎么干!听听这些肺腑之言!
  • 原文地址:https://blog.csdn.net/XLX2339635744/article/details/132714614