spring之@AliasFor

目录

一、介绍

二、使用

2.1、Explicit aliases within an annotation

2.2、Explicit alias for attribute in meta-annotation

2.3、Implicit aliases within an annotation

参考


一、介绍

@AliaFor是一个用于声明注解属性别名的注解。可以让同一个注解里的两个属性成为一个属性,两者互为别名,也可以覆盖元注解的属性。下面是他的定义:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface AliasFor {
	@AliasFor("attribute")
	String value() default "";

	@AliasFor("value")
	String attribute() default "";

	Class<? extends Annotation> annotation() default Annotation.class;
}

有三个属性,value和attribute互为别名,下面是它的api文档说明:

Modifier and TypeOptional Element and Description
java.lang.Class<? extends java.lang.annotation.Annotation>annotation

The type of annotation in which the aliased attribute() is declared.

java.lang.Stringattribute

The name of the attribute that thisattribute is an alias for.

java.lang.Stringvalue

Alias for attribute().

value和attribute指定一个属性名,而被@AliasFor注解的属性名为该属性的别名。比如value是attribute的别名,attribute是value的别名。

二、使用

2.1、Explicit aliases within an annotation

  1. Each attribute that makes up an aliased pair must be annotated with @AliasFor, and either attribute() or value() must reference the other attribute in the pair.
  2. Aliased attributes must declare the same return type.
  3. Aliased attributes must declare a default value.
  4. Aliased attributes must declare the same default value.
  5. annotation() should not be declared.

意思就是同一个注解内可以相互声明别名,下面声明一个@ContextConfiguration

 public @interface ContextConfiguration {

    @AliasFor("locations")
    String[] value() default {};

    @AliasFor("value")
    String[] locations() default {};

    // ...
 }

然后value和location互为别名,注意返回类型和默认值要一致。

2.2、Explicit alias for attribute in meta-annotation

  1. The attribute that is an alias for an attribute in a meta-annotation must be annotated with @AliasFor, and attribute() must reference the attribute in the meta-annotation.
  2. Aliased attributes must declare the same return type.
  3. annotation() must reference the meta-annotation.
  4. The referenced meta-annotation must be meta-present on the annotation class that declares @AliasFor.

通过aliasfor来覆盖元注解的属性,此时不需要默认值了,但需要使用annotation指定元注解,下面声明@XmlTestConfig

 @ContextConfiguration
 public @interface XmlTestConfig {

    @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
    String[] xmlFiles();
 }

声明了@ContextConfiguration的locations属性,此时可以通过@XmlTestConfig的xmlFiles来为@ContextConfiguration的locations赋值。

下面看一个spring文档中的一个例子1.10.2. Meta-annotations

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Scope(WebApplicationContext.SCOPE_SESSION)
public @interface SessionScope {
    @AliasFor(annotation = Scope.class)
    ScopedProxyMode proxyMode() default ScopedProxyMode.TARGET_CLASS;

}

上面第一点说到,必须要使用attribute来指明覆盖的属性,但是这里没有使用,我猜它会自己主动在元注解中找同名的属性吧。

2.3、Implicit aliases within an annotation

  1. Each attribute that belongs to a set of implicit aliases must be annotated with @AliasFor, and attribute() must reference the same attribute in the same meta-annotation (either directly or transitively via other explicit meta-annotation attribute overrides within the annotation hierarchy).
  2. Aliased attributes must declare the same return type.
  3. Aliased attributes must declare a default value.
  4. Aliased attributes must declare the same default value.
  5. annotation() must reference an appropriate meta-annotation.
  6. The referenced meta-annotation must be meta-present on the annotation class that declares @AliasFor.

就是说,同一个注解中的多个属性覆盖了元注解的一个相同的属性,此时,这些属性隐性的互为别名了,注意属性覆盖的传递性。

下面看一个声明:

 @ContextConfiguration
 public @interface MyTestConfig {

    @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
    String[] value() default {};

    @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
    String[] groovyScripts() default {};

    @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
    String[] xmlFiles() default {};
 }

此刻,三个属性同时是元注解locations的别名,那么这三个属性隐性互为别名。

下面看看隐性传递的例子:

 @MyTestConfig
 public @interface GroovyOrXmlTestConfig {

    @AliasFor(annotation = MyTestConfig.class, attribute = "groovyScripts")
    String[] groovy() default {};

    @AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
    String[] xml() default {};
 }

属性覆盖具有传递性,因此这两个属性最终覆盖了@ContextConfiguration的locations属性,因此这两个属性互为别名。

参考

https://docs.spring.io/spring-framework/docs/5.0.3.RELEASE/javadoc-api/org/springframework/core/annotation/AliasFor.html#annotation--

https://docs.spring.io/spring-framework/docs/current/spring-framework-reference/core.html#beans-meta-annotations

https://blog.youkuaiyun.com/jdbdh/article/details/82721178

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值