注解支持@Alias同步值

简介: 注解支持@Alias同步值

你最可爱,我说时来不及思索。但思索之后,还是这样说。——普希金《你多么可爱》

首先是这个issue希望AnnotationUtil增加对@AliasFor的支持

然后我就提交了这个PR提供AnnotationUtil#getAnnotationAlias,为@Alias注解做别名支持的适配

代码如下(找不到方法可以去看hutool源码):

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;
/**
 * 注解工具类<br>
 * 快速获取注解对象、注解值等工具封装
 *
 * @author looly
 * @since 4.0.9
 */
public class AnnotationUtil {
  /**
   * 获取别名支持后的注解
   *
   * @param annotationEle  被注解的类
   * @param annotationType 注解类型Class
   * @param <T>            注解类型
   * @return 别名支持后的注解
   */
  @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别名,关联我们注解中另一个属性:

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;
/**
 * 用于单元测试的注解类<br>
 * 注解类相关说明见:https://www.cnblogs.com/xdp-gacl/p/3622275.html
 *
 * @author looly
 *
 */
// Retention注解决定MyAnnotation注解的生命周期
@Retention(RetentionPolicy.RUNTIME)
// Target注解决定MyAnnotation注解可以加在哪些成分上,如加在类身上,或者属性身上,或者方法身上等成分
@Target({ ElementType.METHOD, ElementType.TYPE })
public @interface AnnotationForTest {
  /**
   * 注解的默认属性值
   *
   * @return 属性值
   */
  String value() default "";
  @Alias("value")
  String retry() default "";
}

然后我们把这个注解加在一个类上面

@AnnotationForTest("测试")
static class ClassWithAnnotation{
    public void test(){
    }
}

我们来获取这个Class上注解的值

@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的值,两者进行了同步

相关文章
|
6月前
|
SQL Java 数据库连接
MyBatis【源码探究 01】mapper.xml文件内<if test>标签判断参数值不等于null和空(当参数值为0)时筛选条件失效原因分析
MyBatis【源码探究 01】mapper.xml文件内<if test>标签判断参数值不等于null和空(当参数值为0)时筛选条件失效原因分析
770 0
MyBatis【源码探究 01】mapper.xml文件内<if test>标签判断参数值不等于null和空(当参数值为0)时筛选条件失效原因分析
|
6月前
|
编译器
【【C++11特性篇】【强制/禁止 】生成默认函数的关键字default&delete(代码演示)
【【C++11特性篇】【强制/禁止 】生成默认函数的关键字default&delete(代码演示)
|
13天前
|
存储 安全 编译器
【c++】深入理解别名机制--引用
本文介绍了C++中的引用概念及其定义、特性、实用性和与指针的区别。引用是C++中的一种别名机制,通过引用可以实现类似于指针的功能,但更安全、简洁。文章详细解释了引用的定义方式、引用传参和返回值的应用场景,以及常引用的使用方法。最后,对比了引用和指针的异同,强调了引用在编程中的重要性和优势。
29 1
|
6月前
|
算法 BI 数据库
MyBatisPlus查询条件设置、映射匹配兼容性、id生成策略、多数据操作
MyBatisPlus查询条件设置、映射匹配兼容性、id生成策略、多数据操作
374 3
|
6月前
|
SQL 存储 Java
MyBatis【付诸实践 02】 mapper文件未编译+statementType使用+返回结果字段顺序不一致+获取自增ID+一个update标签批量更新记录
MyBatis【付诸实践 02】 mapper文件未编译+statementType使用+返回结果字段顺序不一致+获取自增ID+一个update标签批量更新记录
72 0
Ansible 自定义变量与 role 默认变量的合并方法
如果你遇到 failed to combine variables, expected dicts but got a &#39;NoneType&#39; and a &#39;dict&#39; 这样的报错,你可以看看本文。
324 0
cobrautils 使用反射获取 flag 配置, 支持指针字段
cobrautils 使用反射获取 flag 配置, 支持指针字段
124 0
cobrautils 使用反射获取 flag 配置, 支持指针字段
|
前端开发 Java
Springboot 一个注解搞定返回参数key转换 【实用】
Springboot 一个注解搞定返回参数key转换 【实用】
315 0
Springboot 一个注解搞定返回参数key转换 【实用】
|
Java 数据库连接 mybatis
mybatis学习(28):获取自增id方式二(在全局中配置setting选项)
mybatis学习(28):获取自增id方式二(在全局中配置setting选项)
125 0
mybatis学习(28):获取自增id方式二(在全局中配置setting选项)
|
JSON Java 数据格式
SpringMVC中请求参数的绑定【绑定机制、支持的数据类型、使用要求、乱码解决】(超详细)
SpringMVC中请求参数的绑定【绑定机制、支持的数据类型、使用要求、乱码解决】(超详细)
SpringMVC中请求参数的绑定【绑定机制、支持的数据类型、使用要求、乱码解决】(超详细)