本文介绍SpringBoot条件下,借助于AOP实现自定义注解
Meta Annotation元注解
所谓元注解,就是Java提供的、负责修饰其他注解的注解。常见地有:
@Target注解
其定义了注解可以作用的位置,其value属性地常用取值有:
- ElementType.PACKAGE:包
- ElementType.TYPE:类、接口、枚举
- ElementType.FIELD:字段
- ElementType.METHOD:方法
- ElementType.PARAMETER:方法形参
- ElementType.CONSTRUCTOR:构造器方法
@Target注解的value是数组类型,当只有一个元素时,可以省略数组写法。示例如下所示
1 | // 该注解可用于方法上 |
@Retention注解
其定义了注解的生命周期。其value属性地常用取值有:
- RetentionPolicy.SOURCE:在Java源文件中有效。编译器会丢弃掉
- RetentionPolicy.CLASS:在Class文件中有效。运行时JVM会丢弃掉
- RetentionPolicy.RUNTIME:运行时有效。此时即可通过反射获取到该注解
日常开发中,对于@Retention注解而言。我们用的更多的就是RetentionPolicy.RUNTIME了。示例如下
1 | // 该注解保留到运行时 |
@Repeatable注解
默认情况下,注解不可以在同一处重复使用。为此Java 8中引入了@Repeatable注解解决该问题。通过添加@Repeatable注解表示@Family注解可在同一处重复使用。同时,我们需要在@Repeatable注解的值中指定另一个注解@Families。表示可以通过@Families注解的值来包含这个可重复的注解Family。显然此时,@Families中value属性的类型则必须是@Family注解的数组
1 | // 该注解用于字段 (ElementType.FIELD) |
现在,我们就可以在同一处重复使用@Family注解了。下述两种写法均可
1 | public class User { |
自定义注解
自定义注解的基本语法格式如下例所示。其中自定义注解可通过下述形式定义注解属性。可通过default指定属性的默认值,如果不指定默认值,则在使用注解时必须显式设置属性值,而无法使用默认值。需注意属性类型仅限下述几种:
- 基本数据类型(boolean, byte, char, short, int, long, float, double)
- String类型、Class类型、注解类型、枚举类
- 上述类型的数组
1 | /** |
基于AOP实现注解
完成自定义注解后,我们期望在方法上添加注解,能够在调用方法的前后实现日志输出(包含方法入参、方法结果等信息)。这里我们结合SpringBoot的AOP来实现对自定义注解输出日志的功能
1 | /** |
至此,就可以使用该注解了
1 |
|
发送下述请求
1 | curl "127.0.0.1:8080/test/demo1?firstName=Tony&lastName=Wang" |
结果如下所示
发送下述请求
1 | curl "127.0.0.1:8080/test/demo1?lastName=Zhu" |
结果如下所示
Note
如果一个注解中有一个名为value的属性。在使用该注解时,如果只设置value属性的话(要么该注解中只有一个value属性、要么其他属性均使用默认值),则可以省略掉属性名value。如下所示
1 | public class Task { |