网上关于该注解的描述大都抄来抄去,没有涉及到最本质的源码问题, 下面是笔者结合注解源码, 以及其他常用的注解源码, 来分析@AliasFor注解的主要功能以及展示实际使用场景
描述:@AliasFor是一个注解,用于声明注解属性的别名。它有两种不同的应用场景。
我们先来看一下@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))
,想一想我们实际应用中是不是也是这样~
说白了, 就是某个注解内的属性, 功能复制了其他的注解, 比如我们很熟悉的@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
注解的源码, 有兴趣的同学可以看下。
源码如下:
@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
第一个性质,即同一个注解中的两个属性, 互为别名(功能相同))