SpringBoot(十七)自定义注解

目录

自定义注解

前置知识:Java注解之 @Target、@Retention、@Documented简介

@Target({ElementType.TYPE}) 注解

@Retention({RetentionPolicy.Runtime}) 注解

@Documented注解

自定义注解案例

1、pom依赖

2、自定义注解类

3、切面类

4、应用

5、测试


自定义注解

在SpringBoot中,我们可以通过自定义注解来简化代码的编写和提高代码的可读性。下面是使用自定义注解的步骤:

前置知识:Java注解之 @Target、@Retention、@Documented简介

@Target({ElementType.TYPE}) 注解

表示当前注解(@CheckToken)可以打在什么东西上面,此处可以放在类上与方法上

ElementType 这个枚举类型的常量提供了一个简单的分类:注解可能出现在Java程序中的语法位置(这些常量与元注解类型(@Target)一起指定在何处写入注解的合法位置)

package java.lang.annotation;
​
/**
​
 * The constants of this enumerated type provide a simple classification of the
​
 * syntactic locations where annotations may appear in a Java program. These
​
 * constants are used in {@link Target java.lang.annotation.Target}
​
 * meta-annotations to specify where it is legal to write annotations of a
​
 * given type.
​
 * @author  Joshua Bloch
​
 * @since 1.5
​
 * @jls 9.6.4.1 @Target
​
 * @jls 4.1 The Kinds of Types and Values
   */
   public enum ElementType {
   /** 类, 接口 (包括注解类型), 或 枚举 声明 */
   TYPE,
​
   /** 字段声明(包括枚举常量) */
   FIELD,
​
   /** 方法声明(Method declaration) */
   METHOD,
​
   /** 正式的参数声明 */
   PARAMETER,
​
   /** 构造函数声明 */
   CONSTRUCTOR,
​
   /** 局部变量声明 */
   LOCAL_VARIABLE,
​
   /** 注解类型声明 */
   ANNOTATION_TYPE,
​
   /** 包声明 */
   PACKAGE,
​
   /**
​
    * 类型参数声明
      *
    * @since 1.8
      */
      TYPE_PARAMETER,
​
   /**
​
    * 使用的类型
      *
    * @since 1.8
      */
      TYPE_USE
      }
      字段声明(包括枚举常量) */
      FIELD,
​
   /** 方法声明(Method declaration) */
   METHOD,
​
   /** 正式的参数声明 */
   PARAMETER,
​
   /** 构造函数声明 */
   CONSTRUCTOR,
​
   /** 局部变量声明 */
   LOCAL_VARIABLE,
​
   /** 注解类型声明 */
   ANNOTATION_TYPE,
​
   /** 包声明 */
   PACKAGE,
​
   /**
​
    * 类型参数声明
      *
    * @since 1.8
      */
      TYPE_PARAMETER,
​
   /**
​
    * 使用的类型
      *
    * @since 1.8
      */
      TYPE_USE
      }

@Retention({RetentionPolicy.Runtime}) 注解

RetentionPolicy这个枚举类型的常量描述保留注解的各种策略,它们与元注解(@Retention)一起指定注释要保留多长时间

package java.lang.annotation;
/**
​
 * Annotation retention policy.  The constants of this enumerated type
 * describe the various policies for retaining annotations.  They are used
 * in conjunction with the {@link Retention} meta-annotation type to specify
 * how long annotations are to be retained.
   *
 * @author  Joshua Bloch
 * @since 1.5
   */
   public enum RetentionPolicy {
   /**
    * 注解只在源代码级别保留,编译时被忽略
      */
      SOURCE,
      /**
    * 注解将被编译器在类文件中记录
    * 但在运行时不需要JVM保留。这是默认的
    * 行为.
      */
      CLASS,
      /**
       *注解将被编译器记录在类文件中
       *在运行时保留VM,因此可以反读。
    * @see java.lang.reflect.AnnotatedElement
      */
      RUNTIME
      }
      注解将被编译器在类文件中记录
    * 但在运行时不需要JVM保留。这是默认的
    * 行为.
      */
      CLASS,
      /**
       *注解将被编译器记录在类文件中
       *在运行时保留VM,因此可以反读。
    * @see java.lang.reflect.AnnotatedElement
      */
      RUNTIME
      }

@Documented注解

Documented注解表明这个注解是由 javadoc记录的,在默认情况下也有类似的记录工具。 如果一个类型声明被注解了文档化,它的注解成为公共API的一部分。

自定义注解案例

本文以案例验证token为目的开发注解

1、pom依赖

<!--aop启动器-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2、自定义注解类

/**
 * 自定义注解类
 */
//表示当前注解(@CheckToken)可以打在什么东西上面,此处可以放在类上与方法上
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME) //运行时执行
@Documented//指定被修饰的该Annotation可以被javadoc工具提取成文档
public @interface CheckToken {
//    String value() default "";
}

3、切面类

/**
 * 切面类
 */
@Aspect//切面注解
@Component
@SuppressWarnings({"unused"})
public class CheckTokenAspect {
 
    //日志对象
    public static final Logger logger = LoggerFactory.getLogger(CheckTokenAspect.class);
​
    //切入点到自定义注解
    @Pointcut("@annotation(com.yka.annotation.CheckToken)")
    public void annotationPointcut() {
 
    }
 
    //前置通知
    @Before("annotationPointcut()")
    public void beforePointcut(JoinPoint joinPoint) throws Exception {
        // 请求开始时间
        ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String token  = sra.getRequest().getHeader("token");
​
        //控制台日志打印
        logger.info("token为:"+token);
        if (token == null || "".equals(token)) {
            throw new Exception("token为空");//报错打印
        }
        //校验token
    }
 
    @Around("annotationPointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        return joinPoint.proceed();
    }
 
    /**
     * 在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
     * @param joinPoint
     */
    @AfterReturning("annotationPointcut()")
    public void doAfterReturning(JoinPoint joinPoint) {
    }
 
}

4、应用

@RestController
public class AopController {
    @PostMapping("/testPost")
    @CheckToken//自定义注解
    public String postTest(){
        return "aaaaaaaaaaaa";
    }
}

5、测试

测试有token请求体,测试成功

日志打印

测试没有token请求体,测试失败

日志打印:

 

猜你喜欢

转载自blog.csdn.net/m0_65992672/article/details/130451141