用法:
- 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 的作用
互为指定属性, 比如 我们定义的 service, 但如果我们想 @Request("OrderService") 这样指定 service, 就必须使用 @AliasFor
继承注解类中的互为别名关系 如 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);
来源: http://www.bubuko.com/infodetail-3241079.html