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.自定义注解 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;
}

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);
  }
}

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;
  }

打印日志

@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();
  }

打印日志

@AfterThrowing(pointcut = “aopPointCut()”, throwing = “e”)
Spring 自定义注解 面向切面编程_第1张图片

你可能感兴趣的:(java,注解,spring,java,后端)