@AliasFor 原理

 

用法:

 

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);
相關文章
相關標籤/搜索