Java自定义注解

概念

  • 作用在类、方法、成员变量上
  • 业务逻辑无关,有类似切面的概念,起辅助作用
  • 可以在编译和运行时起作用

作用

  • 生成文档。@Param, @Return, @Author, 这些是出现在注释里的
  • 编译时检查,如@Override 注在方法上会检查该方法是否覆盖了超类方法
  • 执行特定切面逻辑如 @Entity, @Transactional

原理

  • 本质是一个继承了Annotation的特殊接口,特殊之处在于 定义时用 public @interface AnnotationName
    • @interface 会标志该自定义接口 继承 java.lang.Annotation 接口
  • 再简化上面这句话,即注解是一种接口,而且是特殊接口
  • 既然是接口, 那实际运行时就会是其实现类,而且该实现类我们未定义
  • 注解的实现类是 Java runtime 生成的动态代理对象$Proxy1,
  • 而且,通过扫描所有类,反射判断其是否有annotation,然后创建代理
  • 且代理是JDK 面向接口的代理
  • 通过代理对象Proxy instance 调用 自定义注解(接口)中的方法,最终调用AnnotationInvocationHandler的invoke方法

元注解

  • java.lang.annotation提供4种元注解,注解自定义注解
    • @Documented- 注解是否包含在JavaDoc中??
    • @Retention- 在哪个阶段起作用,结束这个阶段就可以丢弃了,标志注解的生命周期
      • RetentionPolicy.SOURCE, 编译期间起作用,编译结束后不再有任何意义,编译后丢掉不会写入字节码
        • @Override, @SuppressWarnings
      • RetentionPolicy.CLASS, 在类加载时候起作用,在字节码中存在且被需要,类加载结束则被丢弃,运行时获取不到该注解注解默认声明周期
      • Retention.RUNTIME, 始终不丢弃,运行前保留
        • 反射机制终于可以起到作用了,可以读取该注解
        • 我们自定义注解一般使用这种方式
    • @Target- 注解用于什么地方
      • ElementType.Type, 用于接口(包括注解类型)、类、enum
        • 如 @Entity,@Controller, @Target
      • ElementType.METHOD,
        • 如 @Override
      • ElementType.PARAMETER, 方法参数
        • 如 @RequestParam, @RequestBody
    • @Inherited- 类A被注解了,且该注解标明了@Inherited ,那A的子类会同样被注解,继承性

注解分类

  • 标记类注解,如@Override,@Deprecated, 联想 标记接口,如Serializable,Cloneable
  • 非标记接口

自定义注解的规则

  • 类型定义 @interface,且 不能 再去继承其他接口
  • 参数成员只能用 public 联想,注解本质就是一个接口
  • 参数成员只能是 8 大基本类型和String、Enum、Class、Annotation及 这些类型的数组
  • 要获取类、方法、字段的注解信息,必须通过反射
  • 注解也可以没有定义成员,如标记类注解

总结

  • 注解就是一种标志、判断作用,
  • 与@Override 类标记注解不同,Retention.RUNTIME 类注解是在 运行时起 标记作用,从而对其标志的对象(类、变量、方法等)来添加逻辑
  • 为了更好的规定如何对标志对象增强逻辑,在自定义注解类中添加变量进一步作为判断
  • 联想 @RequestMapping(method=GET), @Transactional(isolation=true) 等
  • 即,运行时标记

你可能感兴趣的:(Java自定义注解)