java动态设置注解值

描述:在运行时根据需求更改注解中的值

一、步骤

1.定义类

public class CadreListQueryDTO extends CadreBaseQueryDTO {

    /**
     * 出国事由
     */
    @QueryField(field = "A21.a2114",type = QueryField.LIKE)
    private String a2114;
}

2.定义方法进行动态设置

    /**
     * 动态设置注解值
     *
     * @param annotation  
     * @param valueName
     * @param value
     * @param <T>
     */
    @SneakyThrows
    public static <T extends Annotation> void setValueToAnnotate(T annotation, String valueName, Object value) {
        InvocationHandler invocationHandler = null;
        if (Objects.nonNull(annotation)) {
            invocationHandler = Proxy.getInvocationHandler(annotation);
        }
        if (Objects.isNull(invocationHandler)) {
            return;
        }
        Field nameField = invocationHandler.getClass().getDeclaredField("memberValues");
        nameField.setAccessible(true);
        Map<String, Object> memberValues = (Map<String, Object>) nameField.get(invocationHandler);
        memberValues.put(valueName, value);
    }

3.测试

 public static void main(String[] args) {
        try {
            QueryField queryField =  CadreListQueryDTO.class.getDeclaredField("a2114").getAnnotation(QueryField.class);
            System.out.println("修改前:"+ queryField.field());
            setValueToAnnotate(queryField,"field","哈哈哈哈");
            System.out.println("修改前:"+ queryField.field());
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

在这里插入图片描述

二、原理分析

  1. AnnotationInvocationHandler是注解的代理hander
  2. 通过反射获取类的注解时会通过AnnotationInvocationHandler创建代理对象并将数据存储到memberValues里
    在这里插入图片描述
  3. 修改memberValues里的数据
    在这里插入图片描述
  4. 获取结果
    在这里插入图片描述

结束!