我有一个自定义Java注释:@DynamicField
public class RESTEndpointInvoker {
@DynamicField(key="httpTimeout")
private long httpTimeout = 8000L;
public void setHttpTimeout(long t){
this.httpTimeout = t;
}
当有人更改与带注释的字段对应的文件或数据库中的值时,请为具有该属性的所有实例调用setter以反映新值。因此,我需要跟踪在地图或其他内容中使用注释的所有实例,以便在外部发生更改时更新它们:
Map<Key,List<Instance>>
注意:我打算使用某种形式的WeakHashMap()
来避免保留对陈旧实例的引用。
理想情况下,我希望在创建实例时收到通知。
我可以scan the classpath用于类类型,然后search each class用于带注释的字段(见下文),但我不确定如何跟踪实时实例。< / p>
//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)){
....
}
}
}
如果这些实例是春季大豆,I can do it,但我宁愿避免这种限制。
答案 0 :(得分:3)
创建此类对象时需要注意。有两种方法:AOP(或其他代码修改)和agentlib。
使用AspectJ(或其他一些AOP系统),您可以在构造这些类的所有对象时获得控制权。要知道要处理哪些构造函数,在编写时,您需要使用注释扫描类的路径。
AspectJ的doc主要描述了在编译时抓取已知的东西,但我有理由相信你可以动态地锁定事物。如果没有,可以应用asm或其他一个codegen工具;例如,请参阅http://zeroturnaround.com/rebellabs/how-to-make-java-more-dynamic-with-runtime-code-generation/,了解您所在社区的某些内容。如果您控制类加载器,则可以通过拦截类加载并注意那些带有注释的文件来避免扫描。
另一种选择是配置文件系统使用的;注册agentlib。这是非常具有侵入性的,不太可能是一个有吸引力的前景。