用法:
import org.springframework.core.annotation.AliasFor; import java.lang.annotation.*; @Target(ElementType.TYPE)//目标是方法 @Retention(RetentionPolicy.RUNTIME) //注解会在class中存在,运行时可通过反射获取 public @interface Request { @AliasFor("service") String value() default ""; @AliasFor("value") String service() default ""; String lang() default "zh-CN"; }
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @RequestMapping(method = RequestMethod.GET) public @interface GetMapping { /** * Alias for {@link RequestMapping#name}. */ @AliasFor(annotation = RequestMapping.class) String name() default "";
AliasFor的作用
1.互为指定属性,比如 我们定义的service,但如果我们想 @Request("OrderService") 这样指定 service,就必须使用@AliasFor
2.继承注解类中的互为别名关系 如GetMapping
@Request(value = "test1") @Slf4j public class Test { @org.junit.Test @GetMapping("test4") public void test4() throws NoSuchMethodException { Request ann = AnnotationUtils.findAnnotation(getClass(),Request.class); System.out.println(ann.value()); System.out.println(ann.service()); GetMapping test4 = AnnotationUtils.findAnnotation(getClass().getMethod("test4"), GetMapping.class); System.out.println(Lists.newArrayList(test4.value())); System.out.println(Lists.newArrayList(test4.path())); RequestMapping rq = AnnotationUtils.findAnnotation(getClass().getMethod("test4"), RequestMapping.class); System.out.println(rq.method()); }
原理:
//AnnotationUtils static <A extends Annotation> A synthesizeAnnotation(A annotation, @Nullable Object annotatedElement) {
//判断当前的注解是否是合成的注解:方法上带有别名的注解。
if (!isSynthesizable(annotationType)) { return annotation; } //如果是合成的注解:构造动态代理,获取互为别名的注解属性。 DefaultAnnotationAttributeExtractor attributeExtractor = new DefaultAnnotationAttributeExtractor(annotation, annotatedElement); InvocationHandler handler = new SynthesizedAnnotationInvocationHandler(attributeExtractor); // Can always expose Spring's SynthesizedAnnotation marker since we explicitly check for a // synthesizable annotation before (which needs to declare @AliasFor from the same package) Class<?>[] exposedInterfaces = new Class<?>[] {annotationType, SynthesizedAnnotation.class}; return (A) Proxy.newProxyInstance(annotation.getClass().getClassLoader(), exposedInterfaces, handler);