文章目录

  • 注解获取属性值的底层实现
  • 注解的工作原理


注解获取属性值的底层实现

JVM会为注解生成代理对象.

注意注解的生命周期都要设置为runtime

java废弃注解是什么 java注解底层实现原理_java废弃注解是什么


程序运行时, 设置如下的jvm参数, 保存生成的代理对象成为文件

-Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true

java废弃注解是什么 java注解底层实现原理_JVM_02


只获取成员属性的值.

java废弃注解是什么 java注解底层实现原理_java_03


运行上面的main方法后 , 生成的代码如下

java废弃注解是什么 java注解底层实现原理_java_04


在生成的代理对象中, 可以看到其中一个是实现了PersonInfoAnnotation这个注解的.

java废弃注解是什么 java注解底层实现原理_JVM_05


这个代理对象声明了9个静态的Method

java废弃注解是什么 java注解底层实现原理_JVM_06


这8个静态的Method, 对应了如下的内容, 除了toString hashCode 等之外, 即声明在注解中的方法.

static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m6 = Class.forName("demo.annotation.PersonInfoAnnotation").getMethod("language");
            m5 = Class.forName("demo.annotation.PersonInfoAnnotation").getMethod("name");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("demo.annotation.PersonInfoAnnotation").getMethod("gender");
            m4 = Class.forName("demo.annotation.PersonInfoAnnotation").getMethod("age");
            m7 = Class.forName("demo.annotation.PersonInfoAnnotation").getMethod("annotationType");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }

在生成的代理对象中, 注解的每一个成员方法, 都会在代理对象中有对应的方法, 例如下图的language 方法和name 方法.

java废弃注解是什么 java注解底层实现原理_java废弃注解是什么_07


其中super是Proxy 代理对象. 如下图所示

java废弃注解是什么 java注解底层实现原理_JVM_08


java废弃注解是什么 java注解底层实现原理_java_09


在代理类中的super.h.invoke中的h是InvocationHandler.

java废弃注解是什么 java注解底层实现原理_java_10


调用的是InvocationHandler 对象的invoke方法.

java废弃注解是什么 java注解底层实现原理_java_11


jvm启动的时候, 加一个额外的参数. -XX:+TraceClassLoading 用于打印出所有加载的类.

java废弃注解是什么 java注解底层实现原理_java废弃注解是什么_12


在控制台打印的信息中, 可以看到加载了AnnotationInvocationHandler 类.

java废弃注解是什么 java注解底层实现原理_JVM_13


AnnotationInvocationHandler 类实现了InvocationHandler 接口.

java废弃注解是什么 java注解底层实现原理_程序运行_14


程序运行的时候, 会执行AnnotationInvocationHandler类中的invoke方法.

java废弃注解是什么 java注解底层实现原理_JVM_15


debug运行程序, 断点打在AnnotationInvocationHandler类中的invoke方法 中, 可以看到memberValues中, 可以获取到注解中的值.

java废弃注解是什么 java注解底层实现原理_程序运行_16


memberValues 的本质是一个map, key的注解的方法名, 值就是给注解赋予的值.

java废弃注解是什么 java注解底层实现原理_java_17

注解的工作原理

  • 通过键值对的方式为注解的属性赋值.
    如下图所示就是通过键值对的方式赋值
  • 编译器会检查注解的使用范围. 将注解的信息, 写入元素的属性表
  • 程序运行时, JVM将RUNTIME 的所有注解属性都取出最终存入map里.
  • JVM会创建AnnotationInvocationHandler 实例, 并传递上一步的map
  • JVM会使用JDK动态代理为注解生成代理类, 并初始化AnnotationInvocationHandler
  • 调用invoke方法, 通过传入方法名, 返回注解对应的属性值.