在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标记的类。
然后您将如何访问组id值,我不确定,在上面的代码中,我在我想要访问的地方使用了XXX。
我说“以某种方式查找堆栈”,但据我所知,用直接Java检查堆栈是不可能的。
也许一种不需要堆栈检查的替代结构是可能的。或者某种AOP字节编织方法是可能的?
目前,我将groupId作为显式构造函数参数传递给系统中的几乎每个对象。让我感到遗憾的是,所有对象都必须维护一个成员变量,这个变量并不是它们逻辑的一部分,而是纯粹用于日志记录。
显式地传递groupId确实有一个优点,就是可以清楚地指出在一些低层次的对象和我的“主”对象之间很难建立创建者关系的情况。
如果您有任何想法如何处理我所描述的注释或字节代码编织,或者您认为传递组is实际上是最好的方法,或者您对于如何实现相同的目标有一些完全不同的想法,那么请告诉我。
/George
更新:注意到,给定主对象的所有“子”对象并不都是在给定的时间点上预先创建的,也就是说,这并不是简单地将组id设置为一些单例,然后让子对象以某种方式访问这个单例对象,因为它们是一起创建的。
发布于 2012-07-05 00:20:45
我想你想要每个控制流方面。每次在切入点中输入方法时,都会创建方面的实例。每次退出控制流时,它都会成为未引用的。它本质上是线程本地的,它将在您想要初始化它的时候被创建。这只是个草图,但我想你会想要这样的:
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从当前主目录复制到新的Foo。
https://stackoverflow.com/questions/10277243
复制相似问题