目次
事前知識: Java アノテーションの @Target、@Retention、@Documented の概要
@Target({ElementType.TYPE}) 注解
@Retention({RetentionPolicy.Runtime}) 注解
カスタム注釈
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 の一部になります。
カスタム注釈のケース
この記事では、ケース検証トークンを目的としたアノテーションを開発します。
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. テスト
テストにはトークン リクエスト本文があり、テストは成功します。
ログの印刷
テストにトークン リクエスト本文がないため、テストは失敗します
ログの印刷: