@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
//...
}
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ContextConfiguration {
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
//...
}
@ContextConfiguration(value = "aa.xml", locations = "bb.xml")
public class AnnotationUtilsTest {
@Test
public void testAliasfor() {
ContextConfiguration cc = AnnotationUtils.findAnnotation(getClass(),
ContextConfiguration.class);
System.out.println(
StringUtils.arrayToCommaDelimitedString(cc.locations()));
System.out.println(StringUtils.arrayToCommaDelimitedString(cc.value()));
}
}
执行测试,报错;value和locations互为别名,不能同时设置;
稍微调整一下代码:
@MyAnnotation
@ContextConfiguration(value = "aa.xml", locations = "aa.xml")
public class AnnotationUtilsTest {
运行测试,均打印出:
aa.xml
aa.xml
2,显示的覆盖元注解中的属性;
先来看一段代码:@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(classes = AopConfig.class)
public class AopUtilsTest {
@Retention(RetentionPolicy.RUNTIME)
@ContextConfiguration
public @interface STC {
@AliasFor(value = "classes", annotation = ContextConfiguration.class)
Class<?>[] cs() default {};
}
1,因为@ContextConfiguration注解本身被定义为@Inherited的,所以我们的STC注解即可理解为继承了@ContextConfiguration注解;
2,我觉得classes属性太长了,所以我创建了一个cs属性,为了让这个属性等同于@ContextConfiguration属性中的classes属性,我使用了@AliasFor标签,分别设置了value(即作为哪个属性的别名)和annotation(即作为哪个注解);
使用我们的STC:
@RunWith(SpringJUnit4ClassRunner.class)
@STC(cs = AopConfig.class)
public class AopUtilsTest {
@Autowired
private IEmployeeService service;
正常运行;
这就是@AliasFor标签的第二种用法,显示的为元注解中的属性起别名;这时候也有一些限制,比如属性类型,属性默认值必须相同;当然,在这种使用情况下,@AliasFor只能为作为当前注解的元注解起别名;
3,在一个注解中隐式声明别名;
这种使用方式和第二种使用方式比较相似,我们直接使用Spring官方文档的例子:
@ContextConfiguration
public @interface MyTestConfig {
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
String[] value() default {};
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
String[] groovyScripts() default {};
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
String[] xmlFiles() default {};
}
可以看到,在MyTestConfig注解中,为value,groovyScripts,xmlFiles都定义了别名@AliasFor(annotation = ContextConfiguration.class, attribute = “locations”),所以,其实在这个注解中,value、groovyScripts和xmlFiles也互为别名,这个就是所谓的在统一注解中的隐式别名方式;
4,别名的传递;
@AliasFor注解是允许别名之间的传递的,简单理解,如果A是B的别名,并且B是C的别名,那么A是C的别名;
我们看一个例子:
@MyTestConfig
public @interface GroovyOrXmlTestConfig {
@AliasFor(annotation = MyTestConfig.class, attribute = "groovyScripts")
String[] groovy() default {};
@AliasFor(annotation = ContextConfiguration.class, attribute = "locations")
String[] xml() default {};
}
转载:https://blog.csdn.net/wolfcode_cn/article/details/80654730
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2