意图
我有一个自定义 Java 注释:@DynamicField
public class RESTEndpointInvoker {
@DynamicField(key="httpTimeout")
private long httpTimeout = 8000L;
public void setHttpTimeout(long t){
this.httpTimeout = t;
}
当有人更改与带注释的字段对应的文件或数据库中的值时,为具有该属性的所有实例调用 setter 以反射(reflect)新值。因此,我需要跟踪 map 或其他内容中使用注释的所有实例,以便在外部发生更改时更新它们:
Map<Key,List<Instance>>
注意:我打算使用某种形式的 WeakHashMap()
来避免保留对过时实例的引用。
问题
如果我无法控制创建这些实例的时间和方式,如何跟踪带注释的任意实例?
理想情况下,我希望在创建实例时收到通知。
尝试过
我可以scan the classpath对于类类型,则 search each class对于带注释的字段(见下文),但我不确定如何跟踪实时实例。
//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)){
....
}
}
}
Spring beans的解决方案
如果这些实例是 spring bean,I can do it ,但我宁愿避免这种限制。
最佳答案
创建此类对象时您需要注意。有两种方法:AOP(或其他代码修改)和agentlib。
使用 AspectJ(或其他一些 AOP 系统),您可以在构造这些类的所有对象时获得控制权。要知道要处理哪些构造函数,您需要在编写时扫描类路径以查找带有注释的类。
AspectJ 的文档主要描述了在编译时获取已知的事物,但我相当确定您可以动态地锁定事物。如果没有,可以应用 asm 或其他 codegen 工具之一;例如,参见 http://zeroturnaround.com/rebellabs/how-to-make-java-more-dynamic-with-runtime-code-generation/讨论您附近的某件事。如果您控制类加载器,则可以通过拦截类加载并注意带有注释的类加载来避免扫描。
另一种选择是由配置文件系统使用的;注册一个agentlib。这是相当具有侵入性的,并且不太可能是一个有吸引力的前景。
关于java - 在 Java 中创建带注释的对象时收到通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28652312/