通俗的理解,注解其实是一种标记,当我们扫描到注解标记的类,方法,属性,可以对这个标记的地方,用反射进行特殊处理加上我们想加上的代码。
元注解:就是底层的注解有@Retention、@Documented、@Target、@Inherited、@Repeatable共5种。
@Retention 用来定义该注解在哪一个级别可用,在源代码中(SOURCE)、类文件中(CLASS)或者运行时(RUNTIME)
@Target表示注解用于什么地方,如类型、方法和域等
@Inherited说明子类可以继承父类中的该注解
扫描注解标记的东西
java中的class method field类 均实现了AnonotateElement接口,提供了对注解相关操作
获取到的注解类是一个代理类
static void getclassAts()throws Exception{
Class aClass = Class.forName("anotation.test");
//获取注解类上注解 只在class类上,不包括成员,方法上的注解
testAnnotation annotation = (testAnnotation)aClass.getAnnotation(testAnnotation.class);
}
static void getMethodAts()throws Exception{
Class aClass = Class.forName("anotation.test");
//获取方法上的指定注解
Method[] methods = aClass.getMethods();
for (Method method : methods) {
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if(annotation instanceof testAnnotation){
System.out.println(((testAnnotation) annotation).type());
System.out.println(((testAnnotation) annotation).value());
}
}
// System.out.println(annotations);
}
}
通过代理对象调用自定义注解(接口)的方法,会最终调用AnnotationInvocationHandler的invoke方法。该方法会从memberValues这个Map中索引出对应的值。而memberValues的来源是Java常量池。
注解是通过键值对的形式为注解属性赋值
通过元注解定义注解使用范围,编译器会检查,并将注解信息写入元素属性表
运行时JVM将RUNTIME的所有注解属性取出并存入map里
map中的值是从常量池中获取
创建AnnotationInvoocationHandler实例并传入前面的map
JVM使用JDK动态代理为注解生成代理类,并初始化处理器
调用invoke方法,通过传入方法名返回注解对应的属性值