SpringBoot (seventeen) custom annotations

Table of contents

custom annotation

Pre-knowledge: Introduction to @Target, @Retention, @Documented of Java annotations

@Target({ElementType.TYPE})

@Retention({RetentionPolicy.Runtime})

@Documented annotation

Custom Annotation Case

1. pom dependency

2. Custom annotation class

3. Noodles

4. Application

5. Test


custom annotation

In SpringBoot, we can simplify code writing and improve code readability through custom annotations. Here are the steps to use custom annotations:

Pre-knowledge: Introduction to @Target, @Retention, @Documented of Java annotations

@Target({ElementType.TYPE})

Indicates what the current annotation (@CheckToken) can be placed on, and it can be placed on the class and method here

ElementType This enumeration type constant provides a simple classification: the syntactic position where the annotation may appear in the Java program (these constants together with the meta-annotation type (@Target) specify where to write the legal position of the annotation)

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 constants of this enumeration type describe various strategies for retaining annotations, which together with meta-annotations (@Retention) specify how long annotations are to be retained

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 annotation

The Documented annotation indicates that this annotation is documented by javadoc, and there is a similar documenting tool by default. If a type declaration is documented with annotations, its annotations become part of the public API.

Custom Annotation Case

This article develops annotations for the purpose of case verification token

1. pom dependency

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

2. Custom annotation class

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

3. Noodles

/**
 * 切面类
 */
@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. Application

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

5. Test

The test has a token request body, and the test is successful

log printing

The test has no token request body, and the test fails

Log print:

 

Guess you like

Origin blog.csdn.net/m0_65992672/article/details/130451141