网上关于该注解的描述大都抄来抄去,没有涉及到最本质的源码问题, 下面是笔者结合注解源码, 以及其他常用的注解源码, 来分析@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第一个性质,即同一个注解中的两个属性, 互为别名(功能相同))