2

Intent

I've got a custom Java annotation: @DynamicField

public class RESTEndpointInvoker {
  @DynamicField(key="httpTimeout")
  private long httpTimeout = 8000L;

  public void setHttpTimeout(long t){
    this.httpTimeout = t;
}

When someone changes a value in a file or database corresponding to the annotated field, invoke the setter for all instances with that property to reflect the new value. So I need to keep track of all instances that use the annotation, in a map or something, to update them when a change occurs externally:

Map<Key,List<Instance>>

Note: I intend to use some form of WeakHashMap() to avoid holding references to stale instances.

Question

How do I track annotated, but arbitrary, instances if I don't control when and how those instances are created?

Ideally, I want to be notified the moment an instance is created.

Tried

I can scan the classpath for class types, then search each class for annotated fields (see below), but I'm not sure how to track live instances.

  //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)){
      ....
    }
  }
}

Solution for Spring beans

If those instances are spring beans, I can do it, but I'd rather avoid that limitation.

Community
  • 1
  • 1
raffian
  • 31,267
  • 26
  • 103
  • 174

1 Answers1

3

You need to take notice when such objects are created. There are two approaches: AOP (or other code modification), and an agentlib.

With AspectJ (or some other AOP system), you can get control at the time that all objects of these classes are constructed. To know which constructors to tackle, you'll need, as you write, to scan the classpath for classes with the annotation.

AspectJ's doc mostly describes grabbing things known at compile time, but I'm reasonably sure that you can latch into things dynamically. If not, asm or one of the other codegen tools can be applied; see for example http://zeroturnaround.com/rebellabs/how-to-make-java-more-dynamic-with-runtime-code-generation/ for a discussion of something in your neighborhood. If you control the class loader, you could avoid scanning by intercepting class loads and noticing those with your annotation.

The other alternative is that used by profile systems; registering an agentlib. This is quite intrusive and not likely to be an attractive prospect.

bmargulies
  • 97,814
  • 39
  • 186
  • 310
  • are you referring to something like this? http://stackoverflow.com/a/16348157/791406, – raffian Feb 21 '15 at 23:22
  • looks interesting for _known_ class types, my concern is unknown types determined at runtime, thanks for pointing me in the right direction – raffian Feb 22 '15 at 00:18