之前一直有一个疑问:在我们获取方法、属性、类、包等等(java.lang.annotation.ElementType枚举类里面的值所代表的类的组成部分都可以)的注解之后,就可以直接通过注解的方法来获取其对应的属性,但是我们知道注解是一个“特殊的接口”,那么问题来了,注解的”实现类”在哪里。。。。
今天通过追踪源码,知道了它是通过动态代理的方式实现的,下面简单的记录一下自己的想法,希望和大家可以多多交流。
首先,注解的RetentionPolicy必须是RUNTIME,只有这样注解才能保留到运行时刻,然后在类加载的过程中,会将注解以键值对的形式(源码里用的LinkedHashMap)存在对应的AnnonationInvocationHandler中(InvocationHandler的实现类,动态代理的重要组成部分,这里对动态代理的内容不太过多介绍了),然后在通过getAnnotation获取注解的时候,会生成对应“注解接口”的代理类,生成代理类的过程中会将对应的AnnonationInvocationHandler放入到此代理类中,然后当执行代理类的“属性方法”(下面贴的代码会说明什么是属性方法)的时候,会执行AnnonationInvocationHandler的invoke方法,在invoke方法中可以获取到“属性方法”的名字,根据这个名字从LinkedHashMap中获取对应的属性值,最后返回~~~
以下是自己打断点的结果:
从这张图可以看出键值对的存储方式是LinkedHashMap;
对应的注解类:
package com.cjs.annotation.first;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
/**
*这个方法就是上面所说的"属性方法"
*/
public int id();
public String description() default "this method has no description ,and it is defalut value";
/**
* The value for annotation attribute UseCase.testDefaultValueIsNull can not be 'null'
*
* @return
*/
/*public Class<?> testDefaultValueIsNull() default null;*/
}
大家有什么疑问可以一起讨论,热烈欢迎~~~这个编辑器好像不能发表情。。。总之非常欢迎大家来交流~^_^