用法:
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);