1

在 GUI 框架中,显式地跟踪父/子关系是很常见的——给定一个任意的 GUI 组件,可以向上浏览“拥有”它的组件的层次结构。

父组件不一定是实际创建其子组件的实体,这些关系通常在创建后配置。

我有一种情况,我感兴趣的是创建关系,即一个对象创建了另一个对象。

所涉及的对象属于不同的类,它们之间一般不存在继承关系等。

实际上,我创建了具有 id 的“主”对象,并且我希望由这些对象创建的所有对象(直接或以 n 度分离)都知道其特定“主”对象的 id。

[ id 实际上仅用于记录目的。]

我可以想象这样的事情:

public class Master
{
    @GroupId
    private final long id;
}

@InheritGroupId
public class Foo
{
    public void bar()
    {
        logger.info("I belong to group {}", XXX);
    }
}

对于 Master 对象,id 将在其构造函数中设置。任何用@InheritGroupId 标记的类在构造时都会以某种方式查找堆栈并查找第一个调用者对象,该对象要么直接通过@GroupId 注释知道其组ID,要么以与此类相同的方式确定它,即一个这也标有@InheritGroupId。

然后你将如何访问 group-id 值我不确定,在上面的代码中,我刚刚在我想访问它的地方使用了 XXX。

我说“以某种方式查找堆栈”,但据我所知,在直接的 Java 中不可能像这样检查堆栈。

也许不需要堆栈检查的替代结构是可能的。或者也许某种 AOP 字节编织方法是可能的?

目前,我将 groupId 作为显式构造函数参数传递给系统中的几乎每个对象。所有对象都必须维护一个成员变量,这对我来说似乎很遗憾,该成员变量并不是其逻辑的一部分,而是纯粹用于日志记录。

显式传递 groupId 确实具有明确指出难以在低级事物和我的“主”对象之一之间建立创建者关系的情况的优势。

如果您对如何处理我用注释或字节码编织所描述的内容有任何想法,或者您认为显式传递 group-ids 实际上是最好的方法,或者您对如何实现相同的想法有一些完全不同的想法事情,那么请告诉我。

/乔治

更新:请注意,给定主对象的所有“子”对象都不是在一个给定时间点预先创建的,也就是说,这不是简单地将 group-id 设置为某个单例然后拥有子对象的问题当它们被大量创建时,以某种方式访问​​这个单例。

4

1 回答 1

0

我认为你想要一个 per-control-flow aspect。每次在切入点中输入方法时,都会创建一个方面的实例。每次退出控制流时,它都会变为未引用。它本质上是线程本地的,它将在您想要初始化它时准确地创建。这只是一个草图,但我想你会想要这样的东西:

aspect GetId percflow(callsFromMaster()) {

    private long id;

    pointcut callsFromMaster() : within(Master.*);
    pointcut childConstructors() : cflow(callsFromMaster()) && execution(Foo.new.(..));

    before(Master master) : callsFromMaster() && this(master) {
        this.id = master.getId();
    }

    after(Foo child) : childConstructors() && this(child) {
        child.id = this.id;
    }

}

我将其解读为:每次您从 Master 方法进入调用的控制流时,创建此方面的新实例。在每次调用之前,保存 ID。在同一控制流中,每次创建新的 Foo 时,都会将 ID 从当前 Master 复制到新的 Foo。

于 2012-07-05T00:20:45.617 回答