Spring注解

注解术语

  • 元注解:注解在别的注解上的注解,比如@Documented、@Retention、@Target

  • 刻板注解:被元注解,用来表明特殊的角色@Controller、@Service、@Repository。Stereotype Annotation 我喜欢翻译它为刻板注解,因为一看到@Repository我就知道这个组件是DAO层的组件,这是一个刻板的印象。

  • 组合注解:被多个元注解,合成多个功能,如@TransactionalService,被@Transactional和@Service两个元注解注解,被@TransactionalService注解的类可以看作添加了这两个注解。

注解存在

  • 在Java8里面,直接存在、间接存在、存在是一样的意思
  • 在Spring里面,如果一个类声明了@TransactionalService,可以说这个类元存在@Transactional和@Service

属性别名和覆盖

  • 显式别名:一个注解里面的两个属性互相使用@AliasFor进行标注。如a1<-->a2,所以a1和a2是显式别名。
public @interface A{
  @AliasFor(attribute="a2")
  String a1();
  @AliasFor(attribute="a1")
  String a2();
}
  • 隐式别名:注解里面的两个或者多个属性使用@AliasFor标注为显式的覆盖元注解上的同一属性,他们是隐式别名。他们指的是当前注解里的两个或者多个属性,跟元注解上的属性没关系。如1->a,b2->a,所以b1和b2是隐式别名。
public @interface A{
  String a();
}
public @interface B{
  @AliasFor(annotation = A.class,attribute="a")
  String b1();
  @AliasFor(annotation = A.class,attribute="a")
  String b2();
}
  • 传递隐式别名:一个注解里面的两个或者多个属性,都使用@AliasFor显式覆盖了元注解上的属性,而且这些属性能通过传递法则有效的覆盖相同的属性,他们是传递性隐式别名。如b1->a1,b2->a2,a1<-->a2,所以b1和b2是传递隐式别名。
public @interface A{
  @AliasFor(attribute="a2")
  String a1();
  @AliasFor(attribute="a1")
  String a2();
}
public @interface B{
  @AliasFor(annotation = A.class,attribute="a1")
  String b1();
  @AliasFor(annotation = A.class,attribute="a2")
  String b2();
}

属性覆盖

  • 一个注解里面的属性覆盖了元注解里面的属性,分为三类

    • 隐式覆盖:注解One的A属性隐式覆盖了Two的A属性
    @Two
    public @interface One{
      String A();
    }
    public @interface Two{
      String A();
    }
    
    • 显式覆盖:注解One的B属性显式覆盖了Two的A属性
    @Two
    public @interface One{
      @AliasFor(annotation = Two.class,attribute="A")
      String B();
    }
    public @interface Two{
      String A();
    }
    
    • 传递显式覆盖:注解One的A属性显式覆盖Two的B属性,Two显式覆盖Three的C属性,那么One的A属性就传递显式覆盖了Three的C属性。
    @Two
    public @interface One{
      @AliasFor(annotation = Two.class,attribute="A")
      String A();
    }
    @Three
    public @interface Two{
      @AliasFor(annotation = Three.class,attribute="C")
      String B();
    }
    public @interface Three{
      String C();
    }
    

问题?

  • @AliasFor能用在@Component和@Qualifier注解的value属性上吗?

    • No!原因:生不逢时。@AliasFor出现的比较晚,为了保持向下兼容,放弃了这部分的支持。
  • 注解为啥这么多弯弯绕绕的东西?

    • 注解不支持继承,这种方式可以有效的对注解进行扩展使用。
  • @AliasFor的原理是什么?

    • 动态代理。通过Spring的AnnotatedElementUtils和AnnotationUtils获取注解信息时,得到的是一个代理对象。创建代理对象过程中会解析@AliasFor注解。
posted @ 2020-12-28 10:51  java拌饭  阅读(122)  评论(0编辑  收藏  举报