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