@AliasFor 注解
Spring 框架提供了很丰富的注解可以让我们很方便的进行 Spring 配置,今天要讲的注解——@AliasFor之前你可能并没有关注过,因为平时开发时我们的确不太会用到。
我关注到这个注解是因为我经常翻看 Spring 的源代码,在 Spring 提供的注解中大量的用到了这个注解,对这个注解不熟悉的话会影响你对代码的判断,而且有些代码看的总是似懂非懂的,很难受(强迫症,哈哈),比如说下面这段代码。
@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 = "nameGenerator")
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
上面的代码大致能“猜测”出 @AliasFor 是为了属性起别名,但是 @AliasFor 的使用场景,使用方式,实现原理是什么?这博客就简单介绍下。
@AliasFor 注解的几种使用方式#
1. 在同一个注解中显示使用,将注解中的多个属性互相设置别名
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
//...
}
为什么要给 value 属性和 path 属相互相设置别名也是有原因的。我们知道在 Spring 中给 value 属性设置值是可以省略属性的,比如可以写成:
RequestMapping("/foo")
这样写比较简洁,但是这样可读性不高,我们并不知道 value 属性代表什么意思。如果给这个属相设置一个 path 别名的话我们就知道这个是在设置路径。
但是要注意一点,@AliasFor 标签有一些使用限制:
- 互为别名的属性属性值类型,默认值,都是相同的;
- 互为别名的注解必须成对出现,比如 value 属性添加了@AliasFor(“path”),那么 path 属性就必须添加@AliasFor(“value”);
- 另外还有一点,互为别名的属性必须定义默认值。
那么如果违反了别名的定义,在使用过程中就会报错。
2. 给元注解中的属性设定别名
@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 {};
//...
}
我们来看 @SpringBootApplication 这个注解,这个注解是有其他几个注解“组合”而成的。下面的代码就是在给@ComponentScan 注解的basePackages属性设置别名scanBasePackages。如果不设置attribute属性的话就是在给元注解的同名属性设置别名。
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
这种使用方式的好处是可以将几个注解的功能组合成一个新的注解。
@AliasFor 的实现代码#
贴大片代码的事就不干了。@AliasFor 的具体实现在AnnotationUtils.findAnnotation 中,代码大家自己翻看吧。
参考#
作者:程序员自由之路
出处:https://www.cnblogs.com/54chensongxia/p/14385621.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
2020-02-07 【源码阅读】为什么需要阅读源码