怎么理解注解?
注解在我的理解下,就是代码中的特殊标记,这些标记可以在编译、类加载、运行时被读取,并执行相应的处理。
都有哪些注解
注解其实在开发中是很常见的,比如我们在使用各种框架的时候(比如说spring)就有很多注解,@Controller,@Praram,@Select等等,一些项目也用到lombokd的注解,@Data,@Slf4j。java原生的注解@Overrid,@Depreated,@Funtional Interface,不过Java原生的注解大多数用于标记和检查。
元注解及作用
原生java注解除了这些提供基本注解之外,还有一种叫做元Annotaion(元注解),所谓元Annotation就是用来修饰注解的,常见的元Annotation有@Retention和@Target;@Retention可以简单的理解为注解设置的生命周期,而@Target表示这个注解可以修饰那些地方(比如说方法,成员变量,包等)
自定义注解
权限认证,背景(springsecurity的原生注解用的时候必须指定拥有那种权限)一般大多数注解都是RUNTIME级别的,因为大多数情况我们是根据运行时环境去做一些处理。开发过程中写自定义注解需要配合反射来使用,因为反射是java获取运行时的信息重要手段,我当时用了自定义注解,在Spring AOP的逻辑处理中,判断是否带有自定义注解,如果有则将监控的逻辑写在方法的前后,这样,只要在方法上加上我的注解,那么就可以进行权限的检验。
解决方案
要写自定义注解,首先要考虑我们什么时候解析这个注解,直接需要我们前面所说的@Retention注解,@Retention注解传入的是RetentionPoloicy枚举,该枚举有三个常量,分别是SOURCE,CLASS,RUNTIME。理解这里得了解从.java文件到class文件再到class被jvm加载的过程了。
从上面的图可以发现有一个注解抽象语法树,这里其实就会去解析注解,然后做处理的逻辑。如果你想要在编译期间处理注解相关的逻辑,你需要继承AbstractProcessor并实现processor方法。比如可以看到lombok就用AnnotationProcessor继承AbstractProcessor。一般来说,只要自定义的注解中@Retention注解设置为SOURCE和CLASS这俩个级别,那么就需要继承并实现,因为SOURCE和CLASS这俩个级别等加载到jvm的时候,注解就被抹除了,从这里又引申出:lombok的注解原理就是在这个(为什么使用了@Data注解就能有set/get等方法,就是在类加载的时候加上去的)
总结:
注解是代码的特殊标记,可以在编译、类加载、运行时被读取,其实对应的就是RetentionPolicy枚举三种级别。SORURCE和CLASS级别需要继承AbstractProcessor,并实现processor方法去处理我们自定义的注解。RUNTIME是我们日常开发中用的最多的。