jjzjj

Spring注解—@AliasFor介绍

AC编程 2023-03-28 原文

一、@AliasFor注解概览

@AliasFor是Spring Framework中的一个注解,从4.2版本开始出现,源码位于spring-core中,用于注解的属性之上,为该属性声明一个别名。

1.1 Spring官方文档说明

查看Spring中的@AliasFor的文档,英文描述如下:
Usage Scenarios

  • Explicit aliases within an annotation: within a single annotation, @AliasFor can be declared on a pair of attributes to signal that they are interchangeable aliases for each other.

  • Explicit alias for attribute in meta-annotation: if the annotation attribute of @AliasFor is set to a different annotation than the one that declares it, the attribute is interpreted as an alias for an attribute in a meta-annotation (i.e., an explicit meta-annotation attribute override). This enables fine-grained control over exactly which attributes are overridden within an annotation hierarchy. In fact, with @AliasFor it is even possible to declare an alias for the value attribute of a meta-annotation.

  • Implicit aliases within an annotation: if one or more attributes within an annotation are declared as attribute overrides for the same meta-annotation attribute (either directly or transitively), those attributes will be treated as a set of implicit aliases for each other, resulting in behavior analogous to that for explicit aliases within an annotation.

1.2 翻译解释说明
1.2.1 Explicit aliases within an annotation

within a single annotation, @AliasFor can be declared on a pair of attributes to signal that they are interchangeable aliases for each other

意思是注解中的属性可以互相为别名进行使用

1.2.2 Explicit alias for attribute in meta-annotation

if the annotation attribute of @AliasFor is set to a different annotation than the one that declares it, the attribute is interpreted as an alias for an attribute in a meta-annotation (i.e., an explicit meta-annotation attribute override). This enables fine-grained control over exactly which attributes are overridden within an annotation hierarchy. In fact, with @AliasFor it is even possible to declare an alias for the value attribute of a meta-annotation.

简略意思是注解中使用了元注解时,可以对元注解的值进行重写,目的是为了能达到和类继承中override相似的功能

1.2.3 Implicit aliases within an annotation

if one or more attributes within an annotation are declared as attribute overrides for the same meta-annotation attribute (either directly or transitively), those attributes will be treated as a set of implicit aliases for each other, resulting in behavior analogous to that for explicit aliases within an annotation.

简略意思是注解中使用了元注解时,可以对元注解的值进行重写,并且可用多个不同的别名进行重写(其实就是一和二的结合)

二、@AliasFor源码说明

2.1 源码
package org.springframework.core.annotation;

import java.lang.annotation.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@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;
}
2.2 说明
2.2.1 annotation属性

声明别名属性的注释类型。默认为注释,这意味着别名属性在与此属性相同的注释中声明。

2.2.2 attribute属性

此属性是其别名的属性的名称。

2.2.3 value属性

用于在未声明注释时代替属性-例如:@AliasFor(“value”)而不是@AliasFor(attribute=“value”)

三、@AliasFor注解的使用场景

  • 在注解中一对属性上通过声明@AliasFor,进行属性互换。

  • 在注解上声明了另一个注解,对另一个注解的属性进行别名覆盖。

  • 在注解中隐示标明属性的别名。

3.1 在注解中一对属性上通过声明@AliasFor,进行属性互换

构成别名对的每个属性都应该用@AliasFor注释,并且属性或值必须引用该对中的另一个属性。由于Spring Framework 5.2.1,从技术上讲,可以只注释别名对中的一个属性;但是,建议在别名对中对这两个属性进行注释,以获得更好的文档以及与Spring Framework早期版本的兼容性。

3.1.1 举例

假设现在有一个注解@MyAnnotationA

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface MyAnnotationA {

   String a1() default "";
}

用这个注解时我们可以像这样@MyAnnotationA(a1=“xxx”),表示a1的属性传入了xxx的值。假设现在我想换一种方式用这个注解,我打算用这样的@MyAnnotationA(a2=“xxx”)实现同样的效果,这时就可以通过别名的方式实现。我们修改@MyAnnotationA

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
public @interface MyAnnotationA {

   @AliasFor("a2")
   String a1() default "";

   @AliasFor("a1")
   String a2() default "";
}
3.1.2 使用说明
  • 必须以属性别名对的形式出现,即要求有两个属性,且这两个属性的名字分别为对方别名。

  • 这两个属性的必须拥有相同的返回值类型。

  • 这两个属性必须拥有相同的默认值。

  • @AliasFor中的annotation()不应该被指定值。

3.1.3 Spring源码中的用法

1、Spring中的@Bean注解

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.core.annotation.AliasFor;

@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
    @AliasFor("name")
    String[] value() default {};

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

    Autowire autowire() default Autowire.NO;

    String initMethod() default "";

    String destroyMethod() default "(inferred)";
}

2、Spring中的@Scope注解

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.annotation.AliasFor;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {

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

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

    ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}
3.2 在注解上声明了另一个注解,对另一个注解的属性进行别名覆盖
3.2.1 举例

再创建一个@MyAnnotationB注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@MyAnnotationA
public @interface MyAnnotationB {

   @AliasFor(annotation = MyAnnotationA.class,value = "a2")
   String value() default "";
}

这时@MyAnnotationB(“vvv”)就和@MyAnnotationA(a2=“vvv”)等价。这里可以理解成,注解MyAnnotationB的value属性重写了注解MyAnnotationA的a2属性,但重新的属性的返回类型必须相同。

3.2.2 使用说明
  • 在需要overrides的注解的属性上使用:@AliasFor(attribute="元注解的属性",annotation="元注解")。

  • 被标记@AliasFor的属性和atttibute所指向的元注解属性必须有相同的返回值类型。

  • @AliasFor中annotation指向的元注解必须作用于正在定义的注解上。

3.2.3 Spring源码中的用法

1、Spring中的@Configuration注解

package org.springframework.context.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
    @AliasFor(
        annotation = Component.class
    )
    String value() default "";
}

可以看出对于value这个属性来说,@Configuration注解中的值会重写@Component的value属性值,这有点像类之间的继承,子类可以重父类的方法。我们也可以将@Configuration注解看成@Component的子注解。

2、Spring中的@SpringBootApplication注解

package org.springframework.boot.autoconfigure;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {@Filter(
    type = FilterType.CUSTOM,
    classes = {TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    Class<?>[] exclude() default {};

    @AliasFor(
        annotation = EnableAutoConfiguration.class
    )
    String[] excludeName() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackages"
    )
    String[] scanBasePackages() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "basePackageClasses"
    )
    Class<?>[] scanBasePackageClasses() default {};

    @AliasFor(
        annotation = ComponentScan.class,
        attribute = "nameGenerator"
    )
    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}
3.3 在注解中隐示标明属性的别名
3.3.1 对注解定义时,对作用于该注解的元注解的同一属性显示指明别名的多个属性互为别名

如下代码,value、groovyScripts和xmlFiles均为元注解@ContextConfiguration中locations的别名,则这三个属性(value、groovyScripts和xmlFiles)也互为别名。

@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 {};
 }
3.3.2 通过别名的传递性隐示标明别名

如下代码,groovy是@MyTestConfig注解中groovyScripts属性的别名,而groovyScripts属性是@ContextConfiguration直接中locations的别名,而xml是@ContextConfiguration直接中locations的别名,所以groovy和xml也互为对方的别名。

@MyTestConfig
 public @interface GroovyOrXmlTestConfig {

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

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

有关Spring注解—@AliasFor介绍的更多相关文章

  1. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  2. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

    ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

  3. spring.profiles.active和spring.profiles.include的使用及区别说明 - 2

    转自:spring.profiles.active和spring.profiles.include的使用及区别说明下文笔者讲述spring.profiles.active和spring.profiles.include的区别简介说明,如下所示我们都知道,在日常开发中,开发|测试|生产环境都拥有不同的配置信息如:jdbc地址、ip、端口等此时为了避免每次都修改全部信息,我们则可以采用以上的属性处理此类异常spring.profiles.active属性例:配置文件,可使用以下方式定义application-${profile}.properties开发环境配置文件:application-dev

  4. ruby-on-rails - Spring 不起作用。 [未初始化常量 Spring::SID::DL] - 2

    我无法运行Spring。这是错误日志。myid-no-MacBook-Pro:myid$spring/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/lib/spring/sid.rb:17:in`fiddle_func':uninitializedconstantSpring::SID::DL(NameError)from/Users/myid/.rbenv/versions/1.9.3-p484/lib/ruby/gems/1.9.1/gems/spring-0.0.10/li

  5. 【云原生】SpringCloud-Spring Boot Starter使用测试 - 2

    目录SpringBootStarter是什么?以前传统的做法使用SpringBootStarter之后starter的理念:starter的实现: 创建SpringBootStarter步骤在idea新建一个starter项目、直接执行下一步即可生成项目。 在xml中加入如下配置文件:创建proterties类来保存配置信息创建业务类:创建AutoConfiguration测试如下:SpringBootStarter是什么? SpringBootStarter是在SpringBoot组件中被提出来的一种概念、简化了很多烦琐的配置、通过引入各种SpringBootStarter包可以快速搭建出一

  6. H2数据库配置及相关使用方式一站式介绍(极为详细并整理官方文档) - 2

    目录H2数据库入门以及实际开发时的使用1.H2数据库的初识1.1H2数据库介绍1.2为什么要使用嵌入式数据库?1.3嵌入式数据库对比1.3.1性能对比1.4技术选型思考2.H2数据库实战2.1H2数据库下载搭建以及部署2.1.1H2数据库的下载2.1.2数据库启动2.1.2.1windows系统可以在bin目录下执行h2.bat2.1.2.2同理可以通过cmd直接使用命令进行启动:2.1.2.3启动后控制台页面:2.1.3spring整合H2数据库2.1.3.1引入依赖文件2.1.4数据库通过file模式实际保存数据的位置2.2H2数据库操作2.2.1Mysql兼容模式2.2.2Mysql模式

  7. Spring Boot集成ElasticSearach - 2

    文章目录前言一、Elasticsearch版本介绍二、客户端种类三、客户端与版本兼容性四、引入Elasticsearch依赖包五、客户端配置六、Elasticsearch使用前言ElasticSearch是Elastic公司出品的一款功能强大的搜索引擎,被广泛的应用于各大IT公司,它的代码位于https://github.com/elastic/elasticsearch,目前是一个开源项目。ElasticSearch公司的另外两个开源产品Logstash、Kibana与ElasticSearch构成了著名的ELK技术栈。。他们三个共同形成了一个强大的生态圈。简单地说,Logstash负责数据

  8. Spring Security 6.0系列【32】授权服务器篇之默认过滤器 - 2

    有道无术,术尚可求,有术无道,止于术。本系列SpringBoot版本3.0.4本系列SpringSecurity版本6.0.2本系列SpringAuthorizationServer版本1.0.2源码地址:https://gitee.com/pearl-organization/study-spring-security-demo文章目录前言1.OAuth2AuthorizationServerMetadataEndpointFilter2.OAuth2AuthorizationEndpointFilter3.OidcProviderConfigurationEndpointFilter4.N

  9. IDEA 2022 创建 Spring Boot 项目详解 - 2

    如何用IDEA2022创建并初始化一个SpringBoot项目?目录如何用IDEA2022创建并初始化一个SpringBoot项目?0. 环境说明1.  创建SpringBoot项目 2.编写初始化代码0. 环境说明IDEA2022.3.1JDK1.8SpringBoot1.  创建SpringBoot项目        打开IDEA,选择NewProject创建项目。        填写项目名称、项目构建方式、jdk版本,按需要修改项目文件路径等信息。        选择springboot版本以及需要的包,此处只选择了springweb。        此处需特别注意,若你使用的是jdk1

  10. ruby-on-rails - 您已经激活了 spring 1.3.6,但是您的 Gemfile 需要 spring 1.3.3。 ( gem ::加载错误) - 2

    我今天遇到了同样的问题,有一个建议:在您的命令前添加bundleexec可能会解决此问题。前置bundleexec没有帮助(我已经这样做了)。springstop和springrestart没有帮助。我需要做的:bundleupdatespring这对我有用。在之前的gemlock文件中使用spring版本是否有更好的解决方案? 最佳答案 我删除gemfile.lock并运行bundle通常会清除一切。否则只需从Gemfile中删除gem"spring"并运行bundle 关于ruby-

随机推荐