在运行时给注解传值

在运行时给注解传值

需求:假设DeviceData类有@Entity这个注解,需要在运行时修改value的值。

@Entity(value="data")
public class DeviceData {
    private String deviceId;    
    private Long timestamp;    
    private String data;
//省略setter、getter...
}

以下代码经测试可行。该代码只是测试,并非完全针对上述需求。

/** 
* Changes the annotation value for the given key of the given annotation to newValue and returns 
* the previous value. 
*/
@SuppressWarnings("unchecked")
public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue){ 
Object handler = Proxy.getInvocationHandler(annotation); 
Field f; 
  try {
     f = handler.getClass().getDeclaredField("memberValues"); 
  } catch (NoSuchFieldException | SecurityException e) { 
      throw new IllegalStateException(e); 
}
f.setAccessible(true); 
Map<String, Object> memberValues; 
try { 
  memberValues = (Map<String, Object>) f.get(handler); 
} catch (IllegalArgumentException | IllegalAccessException e) { 
throw new IllegalStateException(e); 
} 
Object oldValue = memberValues.get(key); 
if (oldValue == null || oldValue.getClass() != newValue.getClass()) { 
throw new IllegalArgumentException(); 
} 
memberValues.put(key,newValue); return oldValue;}

使用例子

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ClassAnnotation { 
String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface FieldAnnotation { 
String value() default "";
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MethodAnnotation { 
String value() default "";
}

@ClassAnnotation("class test")
public static class TestClass{ 
    @FieldAnnotation("field test") 
    public Object field; 
    @MethodAnnotation("method test") 
    public void method(){ }
}

public static void main(String[] args) throws Exception { 

final ClassAnnotation classAnnotation = TestClass.class.getAnnotation(ClassAnnotation.class); 
System.out.println("old ClassAnnotation = " + classAnnotation.value()); 
changeAnnotationValue(classAnnotation, "value", "another class annotation value"); 
System.out.println("modified ClassAnnotation = " + classAnnotation.value()); 

Field field = TestClass.class.getField("field"); 
final FieldAnnotation fieldAnnotation = 
field.getAnnotation(FieldAnnotation.class); 
System.out.println("old FieldAnnotation = " + 
fieldAnnotation.value()); 
changeAnnotationValue(fieldAnnotation, "value", "another field annotation value"); 
System.out.println("modified FieldAnnotation = " + fieldAnnotation.value()); 

Method method = TestClass.class.getMethod("method"); 
final MethodAnnotation methodAnnotation = method.getAnnotation(MethodAnnotation.class); 
System.out.println("old MethodAnnotation = " + methodAnnotation.value()); 
changeAnnotationValue(methodAnnotation, "value", "another method annotation value"); 
System.out.println("modified MethodAnnotation = " + methodAnnotation.value());}

参考链接:http://stackoverflow.com/questions/14268981/modify-a-class-definitions-annotation-string-parameter-at-runtime

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,991评论 19 139
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,778评论 18 399
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,971评论 6 342
  • 我一直坚信着知识是可以改变命运的,而读书是获取知识的一个途径,也是“屌丝逆袭”的一种方式。于我而言,考研便是这条“...
    刘二傻阅读 747评论 0 5
  • 2017/07/23 Update 今天做这题发现这种for+递归并不是我想象的n*n模型,第二个n是堆栈深度,完...
    DrunkPian0阅读 783评论 0 1