Spring 常用注解以及注解的工作原理
Spring常用注解
标准注解:
-
@Override:表示这个方法是重写的,如果父类或者被继承的抽象接口中没有该方法,就会报错 @Deprecated :表示这个方法不再进行维护了 @SuppressWarnings:表示这个方法需要忽略掉一些 报警
元注解:
所谓元注解,就是用来修饰注解的注解,点击看Override可以看到如下代码
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
主要有以下几个:
-
@Rentention 指明注解的生命周期 以下是 Rentention.java的代码,从上述的 Override 可以跳转过去
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { /** * Returns the retention policy. * @return the retention policy */ RetentionPolicy value(); }
然后点击进去可以看到有以下这些hi
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, // 只会出现在源代码中不会出现在 class文件中 /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, // 会出现在源代码和class文件中 /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME // 将目标注解保留到 运行时,可以使用放射机制 }
-
@Target 指定注解的作用目标,或者所修饰的注解的使用范围 packages, types( 类型成员 方法参数和本地变量
和 RetentionPolicy 一样,target也有自己的一个枚举类型,点击进去可以看到。 field 变量,constructor 构造函数,method 成员方法,type_use 任何目标,module 模块
-
@Inherited 表示是否允许子类继承该注解 一旦被这个注解修饰,其子类就会自动继承父类的所有注解。 @Documented 表示被注解对象是否应该被包含在 JavaDoc文档中
自定义注解
在自定义注解的时候注意将 retentionType 设置为 runtime(否则程序没办法在运行的时候使用到这些注解)。并且使用注解需要搭配反射机制,反射机制中不管是类还是Field还是方法,都实现了 annotationElement ,主要有以下几个方法:
-
isAnnotationPresent(判断是指定类型的注解是否存在此元素上,传入一个参数 类/方法/成员变量) getAnnotation(获取单个指定注解,也包括继承的注解,参数传入某个类或者方法或者成员变量) getAnnotations(获取对象上的所有注解,包括继承过来的注解)
注解的工作原理
注解的工作步骤主要由以下几步:
-
通过键值对的形式为注解属性复制 编译器检查注解的使用范围,将注解信息写入元素属性表(也就是CLASS文件) 运行时JVM将RUNTIME的所有注解属性取出并最终存入map里 JVM创建AnnotationInvocationHandler 实例 并且传入 刚才的map JVM使用动态代理机制为注解生成代理类,并初始化处理器 最后通过调用invoke方法,传入方法名返回注解对应的属性值