感觉Spring Boot中的@AliasFor
注解是一个既熟悉又陌生的注解。
说熟悉,是因为我们经常使用的比如@Service
、@RestController
、@Repository
甚至@SpringBootApplication
中都有他们的身影。
说陌生,是因为其实从来没有真正用过这个注解。@AliasFor
注解有两个作用:
- 定义一个注解中的两个属性互为别名。
- 桥接其他注解的属性。
一、定义一个注解中的两个属性互为别名。
我们以ComponentScan
注解为例,先来看下ComponentScan
的定义
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
String resourcePattern() default "**/*.class";
boolean useDefaultFilters() default true;
ComponentScan.Filter[] includeFilters() default {};
ComponentScan.Filter[] excludeFilters() default {};
boolean lazyInit() default false;
@Retention(RetentionPolicy.RUNTIME)
@Target({})
public @interface Filter {
FilterType type() default FilterType.ANNOTATION;
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
String[] pattern() default {};
}
}
以上代码,我们关注点在于
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
这段代码,代表着,在ComponentScan
注解中,basePackages
属性与value
是一样的,可以相互调用。
我们可以测试一下
@ComponentScan(basePackages = {"net.xiangcaowuyu.demo"})
@Component
@EnableAutoConfiguration
@Slf4j
public class DemoApplication {
public static void main(String[] args) {
ComponentScan componentScan = AnnotatedElementUtils.getMergedAnnotation(DemoApplication.class, ComponentScan.class);
assert componentScan != null;
System.out.println(Arrays.toString(componentScan.basePackages()));
System.out.println(Arrays.toString(componentScan.value()));
SpringApplication.run(DemoApplication.class, args);
}
}
二、桥接其他注解的属性
这次,我们看下@Service
的代码
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Service {
@AliasFor(
annotation = Component.class
)
String value() default "";
}
可以看到,@Service
将value
属性,桥接到了@Component
注解的value
属性。
@ComponentScan(basePackages = {"net.xiangcaowuyu.demo"})
@Component
@EnableAutoConfiguration
@Slf4j
public class DemoApplication {
public static void main(String[] args) {
Component component = AnnotatedElementUtils.getMergedAnnotation(BookService.class, Component.class);
assert component != null;
System.out.println(component.value());
SpringApplication.run(DemoApplication.class, args);
}
}
评论 (0)