写在前面:
正如之前所说,注解的作用就是标识和说明
的作用,更多的操作就需要对应的处理器或者代码来实现.
这篇 文章 是我觉得写的最透彻的,但是里面有些细节博主默认我们能懂,所以写的不是很详细,所以最好是写一个自定义注解来DEBUG看具体注解流程.下面我也会简单的总结下注解的一些核心知识.
注解基础:
- 所有的注解类型都继承自这个普通的接口(Annotation)
- 按照注解发挥作用分为两类:
(1)在编译期间给编译器起到提示标识作用的,JDK预定义的三大注解[@Override,@Deprecated,@SuppressWarnings]
(2)在编译期间需要使用注解的属性,使用反射来实现具体的功能.[自定义注解,Spring注解等] - 四个元注解
(1)Target,用来声明注解的作用位置,TYPE(类,接口,枚举),METHOD(方法上),FIELD(属性上),还有参数上,局部变量上,构造方法上,注解上,包上
(2)Retention,注解的保留周期,分为三种,SOURCE(只存在源码上,不会被编译到字节码中),CLASS(类加载时丢弃,会编译到Class中),RUNTIME(永久存在,可以通过反射调用)
(3)Documented存在 ,我们执行 JavaDoc 文档打包时会被保存进 doc 文档
(4)Inherited ,是否可以被注解继承.
注解工作原理:
- 根据注解的保存周期,可以梳理工作原理,比如@Overrider注解,在编译期间,编译器扫描到这个预设注解,会来检查这个注解的位置,是否重写的父类的方法这些,如果没有就报错(当然这类注解不是我们的重点,具体他是如何触发检查的需要你自己了解).
在编译期间,编译器扫描类,发现注解会将注解添加到类或者是方法的属性中的annotations中,这个注解里面都存储了注解在当前实体的所有注解,每个注解里面有handle和一个Map,map里面存储的是注解里面的属性(Key)和值(Value),如果需要会给这个注解创建代理对象,对象继承自代理类Proxy,同时实现这个注解的接口,里面实现了注解的所有方法,同时注解的方法实质上是调用Proxy类中的invoke()这个方法,返回对应的值. - 当然像Spring注解,并不是仅仅通过注解来实现的那些复杂操作,而是通过注解处理器(注解后置处理器)来实现的.