注解分类
JAVA 原生注解:
- @Overried、@Deprecated 等,大多数用于「标记」和「检查」
框架定义的注解:
- Spring 的@Controller、@Component 等,Lombok 的@Data、@Builder 等
元注解:
- 所谓的元 Annotation 就是用来修饰注解的
- 常用的元 Annotation 有@Retention 和@Target
- @Retention 注解可以简单理解为设置注解的生命周期
- @Target 表示这个注解可以修饰哪些地方(比如方法、还是成员变量、还是包等等)
注解的生命周期
如果要自定义注解,必须关心它的生命周期。
@Retention 注解会修饰我们自定义注解生命周期。@Retention 注解传入的是 RetentionPolicy 枚举,该枚举有三个常量,分别是 SOURCE、CLASS 和 RUNTIME
- SOURCE 代表着注解仅保留在源码级别中,在编译器会被处理,不会带到字节码文件中
- CLASS 代表着注解在字节码文件中保留,但不会被 JVM 加载到内存
- RUNTIME 代表着注解被 JVM 加载到内存时仍保留,因此运行时环境可以使用它
JAVA 编译阶段有一个过程为「注解抽象语法树」,这里其实就会去解析生命周期为 SOURCE 的注解,然后做处理的逻辑。
JDK 提供了 Hook,我们想要在编译时期做注解相关的事,可以继承 AbstractProcessor 并实现 process 方法。比如可以看到 lombok 就用 AnnotationProcessor 继承了 AbstractProcessor,这就是为什么使用了个@Data 这样的注解就能有 set/get 等方法了,就是在这里加上去的