@AliasFor注解详解(结合源码分析)
Posted 来老铁干了这碗代码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了@AliasFor注解详解(结合源码分析)相关的知识,希望对你有一定的参考价值。
一. 概述
网上关于该注解的描述大都抄来抄去,没有涉及到最本质的源码问题, 下面是笔者结合注解源码, 以及其他常用的注解源码, 来分析@AliasFor注解的主要功能以及展示实际使用场景
描述:@AliasFor是一个注解,用于声明注解属性的别名。它有两种不同的应用场景。
- 同一个注解中的两个属性, 互为别名(功能相同)
- 帮助某个属性继承其他注解的功能
二. 功能
1. 同一个注解中的两个属性, 互为别名(功能相同)
我们先来看一下@AliasFor的源码
@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;
@AliasFor
源码本身就用到了第一个特点,即:@AliasFor(value=“xxx”)
等价@AliasFor(attribute=“xxx”)
。
下面是一个@AliasFor
注解在请求映射注解@RequestMapping
中的实际应用, 看一下@RequestMapping
注解的源码:
@Target(ElementType.METHOD, ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping
String name() default "";
@AliasFor("path")
String[] value() default ;
@AliasFor("value")
String[] path() default ;
RequestMethod[] method() default ;
String[] params() default ;
String[] headers() default ;
String[] consumes() default ;
String[] produces() default ;
可以看到,按照@AliasFor
注解的第一个特点,@RequestMapping(path=(xxx))
等价于@RequestMapping(value=(xxx))
,想一想我们实际应用中是不是也是这样~
2. 帮助某个属性继承其他注解的功能
说白了, 就是某个注解内的属性, 功能复制了其他的注解, 比如我们很熟悉的@Service
和@Component
等价, 原因就是@Serivce
注解内部定义了@AliasFor
。
@Serivce
源码如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service
@AliasFor(annotation = Component.class)
String value() default "";
可以看到,@Service
的value
值, 即为@Component
,也就是说,@Service(value = "xxx")
等价于@Component(value = "xxx")
, 进一步推导出,@Service
和@Component
等价。
同理,@Component、@Repository、@Service、@Controller
四个注解相互等价
以上就是关于@AliasFor
的两个性质, 下面我分析了@SpringBootApplication
注解的源码, 有兴趣的同学可以看下。
三. 分析@SpringBootApplication注解源码
源码如下:
@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,
attribute = "exclude"
)
Class<?>[] exclude() default ;
@AliasFor(
annotation = EnableAutoConfiguration.class,
attribute = "excludeName"
)
String[] excludeName() default ;
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default ;
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default ;
综合@AliasFor注解的功能特点, 可得如下结论:
@SpringBootApplication
由@SpringBootConfiguration
、@EnableAutoConfiguration
、@ComponentScan
组成(这个结论与@AliasFor无关, 是SpringBoot的注解继承特性)
代码片段如下(摘取自@SpringBootApplication
源码):
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = @Filter(
type = FilterType.CUSTOM,
classes = TypeExcludeFilter.class
)
@SpringBootApplication(excludeName = "xxx")
等价于@EnableAutoConfiguration(excludeName="xxx")
代码片段如下(摘取自@SpringBootApplication
源码):
@AliasFor(
annotation = EnableAutoConfiguration.class,
attribute = "exclude"
)
Class<?>[] exclude() default ;
@AliasFor(
annotation = EnableAutoConfiguration.class,
attribute = "excludeName"
)
String[] excludeName() default ;
其中,annotation
表示注解名,attribute
表示这个注解内的关键字, String[] excludeName() default ;
表示该注解+关键字代指@SpringBootApplication
中的关键字(根据@AliasFor
第二个性质,即帮助某个属性继承其他注解的功能)
excludeName
关键字等价于exclude
关键字, 根据@AliasFor
第一个性质,即同一个注解中的两个属性, 互为别名(功能相同))
以上是关于@AliasFor注解详解(结合源码分析)的主要内容,如果未能解决你的问题,请参考以下文章