在Java中创建带注释的对象时收到通知
意图
我有一个自定义的Java注释: @DynamicField
public class RESTEndpointInvoker { @DynamicField(key="httpTimeout") private long httpTimeout = 8000L; public void setHttpTimeout(long t){ this.httpTimeout = t; }
当有人更改与带注释的字段对应的文件或数据库中的值时,为具有该属性的所有实例调用setter以反映新值。 因此,我需要跟踪在地图或其他内容中使用注释的所有实例,以便在外部发生更改时更新它们:
Map<Key,List>
注意:我打算使用某种forms的WeakHashMap()
来避免保持对陈旧实例的引用。
题
如果我不控制何时以及如何创建这些实例,如何跟踪带注释但任意的实例?
理想情况下,我希望在创建实例时收到通知。
试着
我可以扫描类路径中的类类型 ,然后在每个类中搜索带注释的字段(见下文),但我不确定如何跟踪实例。
//get classes with annotation Reflections r = new Reflections("com.foo", new TypeAnnotationsScanner()); Set<Class> allAnnotated = r.getTypesAnnotatedWith(DynamicField.class); //identify fields for(Class cls : allAnnotated){ for(Field field : cls.getDeclaredFields()){ Class type = field.getType(); String name = field.getName(); if(field.isAnnotationPresent(DynamicField.class)){ .... } } }
春豆的解决方案
如果这些实例是春豆, 我可以做到 ,但我宁愿避免这种限制。
创建此类对象时需要注意。 有两种方法:AOP(或其他代码修改)和agentlib。
使用AspectJ(或其他一些AOP系统),您可以在构造这些类的所有对象时获得控制权。 要知道要处理哪些构造函数,在编写时,您需要使用注释扫描类的路径。
AspectJ的doc主要描述了在编译时抓取已知的东西,但我有理由相信你可以动态地锁定事物。 如果没有,可以应用asm或其他一个codegen工具; 例如,请参阅http://zeroturnaround.com/rebellabs/how-to-make-java-more-dynamic-with-runtime-code-generation/,了解您所在社区的相关信息。 如果您控制类加载器,则可以通过拦截类加载并注意带有注释的加载来避免扫描。
另一种选择是配置文件系统使用的; 注册agentlib。 这是非常具有侵入性的,不太可能是一个有吸引力的前景。