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 を直接知っているか、このクラスと同じ方法でグループ ID を決定した最初の呼び出し元オブジェクトを探します。これも @InheritGroupId でマークされていました。

group-id 値にどのようにアクセスするかはわかりません。上記のコードでは、アクセスしたい場所で XXX を使用しただけです。

「どうにかしてスタックを調べろ」と言いますが、私の知る限り、そのままの Java ではこのようにスタックを調べることはできません。

たぶん、スタック検査を必要としない代替構造が可能です。それとも、ある種の AOP バイト ウィービング アプローチが可能でしょうか?

現在、システム内のほぼすべてのオブジェクトに明示的なコンストラクター引数として groupId を渡しています。すべてのオブジェクトが、実際にはロジックの一部ではなく、純粋にログ記録に使用されるメンバー変数を維持する必要があることは、私には残念なことです。

groupId を明示的に渡すことには、下位の何かと私の「マスター」オブジェクトの 1 つとの間に作成者の関係を確立することが難しい状況を明確に指摘できるという利点があります。

私が説明したことを注釈やバイトコード ウィービングで処理する方法について何らかのアイデアがある場合、またはグループ ID を明示的に渡すことが実際には最良の方法であると考えている場合、またはほとんど同じことを達成する方法についてまったく異なる考えをお持ちの場合事、それから私に教えてください。

/ジョージ

更新:特定のマスター オブジェクトのすべての「子」オブジェクトが、特定の時点ですべて事前に作成されるわけではないことに注意してください。まとめて作成されるため、何らかの方法でこのシングルトンにアクセスします。

4

1 に答える 1

0

コントロールフローごとのアスペクトが必要だと思います。ポイントカットにメソッドを入力するたびに、アスペクトのインスタンスが作成されます。制御フローを終了するたびに、参照されなくなります。これは本質的にスレッドローカルであり、初期化したいときに正確に作成されます。これは単なるスケッチですが、次のようなものが必要だと思います。

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 にコピーします。

于 2012-07-05T00:20:45.617 に答える