你最可爱,我说时来不及思索。但思索之后,还是这样说。——普希金《你多么可爱》
首先是这个issue
:希望AnnotationUtil
增加对@AliasFor
的支持
然后我就提交了这个PR
:提供AnnotationUtil#getAnnotationAlias
,为@Alias
注解做别名支持的适配
代码如下(找不到方法可以去看hutool
源码):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
| import cn.hutool.core.exceptions.UtilException; import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil;
import java.lang.annotation.Annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.annotation.*; import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map;
public class AnnotationUtil {
@SuppressWarnings("unchecked") public static <T extends Annotation> T getAnnotationAlias(AnnotatedElement annotationEle, Class<T> annotationType) { T annotation = getAnnotation(annotationEle, annotationType); Object o = Proxy.newProxyInstance(annotationType.getClassLoader(), new Class[]{annotationType}, (proxy, method, args) -> { Alias alias = method.getAnnotation(Alias.class); if (ObjectUtil.isNotNull(alias) && StrUtil.isNotBlank(alias.value())) { Method aliasMethod = annotationType.getMethod(alias.value()); return ReflectUtil.invoke(annotation, aliasMethod); } return method.invoke(args); }); return (T) o; } }
|
最终效果路哥进行了一些调整
然后使用方式也很简单,我们写一个注解,然后给它用一个@Alias
别名,关联我们注解中另一个属性:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| package cn.hutool.core.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.TYPE }) public @interface AnnotationForTest {
String value() default "";
@Alias("value") String retry() default ""; }
|
然后我们把这个注解加在一个类上面
1 2 3 4 5
| @AnnotationForTest("测试") static class ClassWithAnnotation{ public void test(){ } }
|
我们来获取这个Class
上注解的值
1 2 3 4 5 6 7 8 9
| @Test public void getAnnotationSyncAlias() { Assert.assertEquals("", ClassWithAnnotation.class.getAnnotation(AnnotationForTest.class).retry());
AnnotationForTest annotation = AnnotationUtil.getAnnotationAlias(ClassWithAnnotation.class, AnnotationForTest.class); Assert.assertEquals("测试", annotation.retry()); }
|
大家可以很明显地看出来,这里我们默认给AnnotationForTest
上的value
赋值,但我们取retry
,因为我们加了@Alias
注解且使用了getAnnotationSyncAlias
方式获取,所以我们取到的retry
值实际上是value
的值,两者进行了同步