在 Java 中创建带注释的对象时收到通知 [英] Get notified when annotated objects are created in Java

查看:20
本文介绍了在 Java 中创建带注释的对象时收到通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义的 Java 注释:@DynamicField

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;
}

当有人更改与注释字段对应的文件或数据库中的值时,为具有该属性的所有实例调用 setter 以反映新值.所以我需要在地图或其他东西中跟踪所有使用注释的实例,以便在外部发生更改时更新它们:

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>>

注意:我打算使用某种形式的 WeakHashMap() 来避免持有对陈旧实例的引用.

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

理想情况下,我希望在创建实例时收到通知.

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

我可以扫描类路径以查找类类型,然后搜索每个类以获取带注释的字段(见下文),但我不确定如何跟踪实时实例.

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

Spring bean 的解决方案

如果这些实例是 spring bean,我可以做到,但我宁愿避免这种限制.

Solution for Spring beans

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

推荐答案

创建此类对象时需要注意.有两种方法:AOP(或其他代码修改)和 agentlib.

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

使用 AspectJ(或其他一些 AOP 系统),您可以在构造这些类的所有对象时获得控制权.要知道要处理哪些构造函数,您需要在编写时扫描带注释的类的类路径.

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 的文档主要描述了在编译时获取已知内容,但我有理由确信您可以动态锁定事物.如果没有,可以应用 asm 或其他代码生成工具之一;参见例如 http://zeroturnaround.com/rebellabs/how-to-make-java-more-dynamic-with-runtime-code-generation/ 讨论您附近的一些事情.如果您控制类加载器,则可以通过拦截类加载并通过注释注意那些加载来避免扫描.

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.

另一种选择是配置文件系统使用的;注册一个agentlib.这是相当侵入性的,不太可能是一个有吸引力的前景.

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

这篇关于在 Java 中创建带注释的对象时收到通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆