动态修改属性的注解值

TestAnno

package com.ymqx.动态修改类属性的注解值;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnno {
    String name() default "";
    String type() default "1";
}

DynamicChangeAnnoUtils

package com.ymqx.动态修改类属性的注解值;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Map;

/*
 * 思路:
 * 1、先获取需要修改的 Field
 * 2、通过 Field 的方法 getDeclaredField 获取需要修改的注解
 * 3、Proxy.getInvocationHandler(anno) 获取该注解代理实例所持有的 InvocationHandler
 * 4、获取 AnnotationInvocationHandler 的 memberValues 字段
 * 5、获取 memberValuesMap,通过该Map 对注解属性值获取修改
 *
 * @Param dest : 需要修改的对象
 * @Param changeProperties : 类属性下注解需要修改的集合
 */
public class DynamicChangeAnnoUtils {
    public static void changeAnnoValue(Object dest, Map<String, Map<String, Map<String, String>>> changeProperties) {
        for (String filedKey: changeProperties.keySet()) {
            //System.out.println("filedKey=" + filedKey);
            try {
                Field field = dest.getClass().getDeclaredField(filedKey);
                for (String annoKey : changeProperties.get(filedKey).keySet()) {
                    //System.out.println("annoKey=" + annoKey);
                    //获取字段上的注解实例
                    Annotation[] annotations = field.getDeclaredAnnotations();
                    for (Annotation anno : annotations) {
                        //System.out.println(anno);
                        if (anno.annotationType().getSimpleName().equals(annoKey)) {
                            //System.out.println(anno.annotationType().getSimpleName());
                            // 1、获取代理实例所持有的 InvocationHandler
                            InvocationHandler handler = Proxy.getInvocationHandler(anno);
                            // 2、获取 AnnotationInvocationHandler 的 memberValues 字段
                            Field mValuesField = handler.getClass().getDeclaredField("memberValues");
                            // 3、打开访问权限
                            mValuesField.setAccessible(true);
                            // 4、获取 memberValuesMap
                            Map memberValuesMap = (Map) mValuesField.get(handler);
                            // 5、put修改注解属性值
                            changeProperties.get(filedKey).get(annoKey).forEach((k, v) -> {
                                //System.out.println("k=" + k + ",v=" + v);
                                memberValuesMap.put(k, v);
                            });
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

TestBean

package com.ymqx.动态修改类属性的注解值;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;

public class TestBean {

    @TestAnno (name = "test")
    private String val;

    public String getVal() {
        return val;
    }

    public void setVal(String val) {
        this.val = val;
    }

    public TestBean(String val) {
        this.val = val;
    }

    public TestBean() {
    }

    public static void main(String[] args) {
        TestBean testBean = new TestBean();
        printAnno(testBean);

        HashMap<String, String> annoValueMap = new HashMap<>();
        annoValueMap.put("name","change");
        annoValueMap.put("type","2");

        HashMap<String, Map<String, String>> annoMap = new HashMap<>();
        annoMap.put("TestAnno", annoValueMap);

        HashMap<String, Map<String, Map<String, String>>> filedMap = new HashMap<>();
        filedMap.put("val", annoMap);

        System.out.println("+++修改注解属性值后+++");
        DynamicChangeAnnoUtils.changeAnnoValue(testBean, filedMap);
        printAnno(testBean);
    }

    public static void printAnno(Object obj) {
        // 遍历获取Field[] 集合
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field f : declaredFields) {
            // 遍历获取Annotation[] 集合
            Annotation[] annotations = f.getDeclaredAnnotations();
            for (Annotation anno : annotations) {
                //System.out.println(anno);  //@com.ymqx.动态修改类属性的注解值.TestAnno(name=test, type=1)
                //System.out.println(anno.annotationType().getName());  //com.ymqx.动态修改类属性的注解值.TestAnno
                //System.out.println(anno.annotationType().getSimpleName());  //TestAnno

                if (anno.annotationType().getSimpleName().equals("TestAnno")) {
                    // 1、获取代理实例所持有的 InvocationHandler
                    InvocationHandler handler = Proxy.getInvocationHandler(anno);
                    try {
                        // 2、获取 AnnotationInvocationHandler 的 memberValues 字段
                        Field mValuesField = handler.getClass().getDeclaredField("memberValues");
                        // 3、打开访问权限
                        mValuesField.setAccessible(true);
                        // 4、获取 memberValuesMap
                        Map memberValuesMap = (Map) mValuesField.get(handler);
                        // 5、get获取注解属性值
                        System.out.println(memberValuesMap.get("name"));
                        System.out.println(memberValuesMap.get("type"));
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

运行结果:

test
1
+++修改注解属性值后+++
change
2

https://www.codenong.com/12248897/
https://blog.csdn.net/qq_42553504/article/details/124313431
https://www.csdn.net/tags/NtTaUgysMDg1OTUtYmxvZwO0O0OO0O0O.html
https://www.w3cschool.cn/article/35230124.html

你可能感兴趣的:(Java,java)