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

<think>嗯,用户问的是@AliasFor注解的意思。首先,我需要确定用户的技术背景。可能是在使用Spring框架时遇到了这个注解,或者在阅读源码时看到的。Spring中的注解经常用到,而@AliasForSpring核心的一个元注解,用于处理注解属性之间的别名关系。 接下来,我应该回忆这个注解的具体作用。记得它主要是让一个注解中的两个属性互为别名,也就是说,它们实际上代表同一个值。比如在Spring MVC的@RequestMapping中,path和value属性就是通过@AliasFor互相关联的,这样用户用哪个都可以。 然后,需要考虑用户可能的使用场景。用户可能在自定义注解时想要简化属性,或者想理解现有注解中的属性为何可以互换使用。这时候解释@AliasFor的作用和用法就很重要了。 另外,要确保回答结构清晰。可能需要分点说明,比如定义、作用、使用场景、示例等。还要注意使用中文,并且按照系统指令使用正确的LaTeX格式,比如行内公式用$...$,独立公式用$$...$$,不过这个问题可能不太涉及数学公式,但如果有代码示例,需要用代码块标记。 还要检查是否有常见的误解需要澄清,比如@AliasForSpring的版本关系,或者与其他注解的区别。比如,在Spring Framework中,这个注解是从4.2版本开始引入的,可能需要提到版本兼容性问题,但用户没有具体问到这个,可能暂时不需要深入,但可以简单提一下。 最后,确保语言通俗易懂,避免过于技术化的术语,但因为是注解的解释,适当的技术术语是必要的。可能还需要给出实际的代码示例,比如自定义一个注解,展示如何使用@AliasFor,这样用户能更直观地理解。</think>在Spring Framework中,`@AliasFor`注解是一个元注解(用于注解其他注解的注解),主要作用是声明注解属性的**别名关系**。它的核心功能可以概括为: $$\text{属性别名} \Rightarrow \text{同一个配置项的多种表达方式}$$ ### 主要作用 1. **属性别名** 允许一个注解中的两个属性互为别名,例如Spring MVC中的`@RequestMapping`: ```java @RequestMapping public @interface RequestMapping { @AliasFor("path") String[] value() default {}; @AliasFor("value") String[] path() default {}; } ``` 此时`value`和`path`完全等价,写`@RequestMapping("/test")`等同于`@RequestMapping(path="/test")` 2. **跨注解继承** 允许子注解属性覆盖父注解属性并建立别名关系,例如`@GetMapping`继承自`@RequestMapping`: ```java @RequestMapping(method = RequestMethod.GET) public @interface GetMapping { @AliasFor(annotation = RequestMapping.class, attribute = "path") String[] value() default {}; } ``` 这里`@GetMapping`的`value`属性实际上是`@RequestMapping`的`path`属性的别名 ### 典型使用场景 1. **简化注解配置** 例如让`value`作为默认属性,其他属性作为显式命名属性 2. **注解重构兼容** 当需要修改属性名称时,通过别名保持向前兼容 3. **组合注解** 在自定义组合注解时,通过别名将多个注解的配置项统一暴露 ### 关键特性 - 必须成对使用(两个属性互相标记为别名- 默认要求别名属性类型一致 -Spring 4.2+版本中正式引入 - 运行时可通过`AnnotatedElementUtils`解析别名关系 使用示例: ```java @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation { @AliasFor("location") String value() default ""; @AliasFor("value") String location() default ""; } // 使用时等价 @MyAnnotation("home") @MyAnnotation(location = "home") ```
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值