ユーザー selig は正しいです。おそらく、すべてのオブジェクトの作成、特に JDK/JRE クラスの作成をインターセプトしたくないでしょう。しかし、それが価値があるために、何が機能し、どのように機能し、何が機能しないかについての説明は次のとおりです。
ちょっとしたドライバー アプリケーション:
public class Application {
public static void main(String[] args) {
new Application();
new String();
}
}
さまざまなタイプのコンストラクター関連のポイントカット/アドバイスを含むアスペクト:
public aspect ObjectCreationAspect {
before() : preinitialization(*.new(..)) && !within(ObjectCreationAspect) {
System.out.println(thisJoinPointStaticPart);
}
before() : initialization(*.new(..)) && !within(ObjectCreationAspect) {
System.out.println(thisJoinPointStaticPart);
}
before() : call(*.new(..)) && !within(ObjectCreationAspect) {
System.out.println(thisJoinPointStaticPart);
}
before() : execution(*.new(..)) && !within(ObjectCreationAspect) {
System.out.println(thisJoinPointStaticPart);
}
}
ウーブン ドライバー アプリケーションの出力:
call(Application())
preinitialization(Application())
initialization(Application())
execution(Application())
call(java.lang.String())
説明:
AspectJ にはさまざまな種類のウィービングがあります。
- Compile-time weaving (CTW): ajc (AspectJ コンパイラ) によってコンパイルされたクラスのみを織り込むことができます。これには、JDK/JRE クラスと、ソースからコンパイルしないサードパーティ ライブラリも含まれません。上記のサンプル出力は、コンパイル時のウィービングの効果を示しています。
- バイナリ ウィービング (BW): AspectJ コンパイラは、アスペクト コードを既存のバイト コードに直接コンパイルするために使用されます。これは、サードパーティのライブラリだけでなく、独自のプリコンパイル済みアプリケーション クラスでも機能します。AspectJ コンパイラの in-pathにrt.jarを配置すると、理論的には JDK/JRE クラスでも動作します。JDK/JRE の織り方は少しトリッキーですが、私は以前にやったことがあります。アプリケーションを起動するときに JDK/JRE の boot-classpath の先頭に追加する、いくつかの JDK クラスを組み合わせたrt.jarの新しく編まれたバージョンまたは単なる小さな JAR ファイルを生成できます。
- Load-time weaving (LTW): 基本的にこれは BW ですが、クラスの読み込み中に動的に行われます。この AspectJ シナリオでは、アスペクト ウィーバーの影響下でクラスローダーによってロードされるクラスのみを織り込むことができます。したがって、独自のコードとサードパーティのライブラリでは機能しますが、通常、アスペクト ウィーバーがロードされる前にロードされる JDK/JRE ブートストラップ クラスでは機能しません。これは卵と鶏の問題です。ウィーバーは JRE をロードする前に JRE を実行する必要がありますが、JRE クラスをウィービングするには、それらのクラスがブートストラップされる前にウィーバーがそこにいる必要があります。
これで簡単にできることは、独自のコードまたはサードパーティのコードから JDK/JRE コンストラクターへの呼び出しcall(java.lang.String())
をインターセプトすることです。これは、ログ出力行で. ただし、JRE クラスから JRE クラスへの内部呼び出しをインターセプトすることはできません。
そうは言っても、あなたはどんな恐ろしいことをしたいのだろうと本当に思います。つまり、あなたはそれを説明しますが、それは途方もない設計エラーのように聞こえます。または、車輪を再発明して、すでに存在するある種のプロファイラーまたはデバッガーを書きたいとします。個々のオブジェクトの作成を傍受することで何を期待できますか? ログに記録している文字列だけの場合、アプリケーションの速度が大幅に低下し、メモリ消費が大幅に増加し、さらに多くのオブジェクトが作成されます。自分が本当にやりたいことは何なのか、もう一度考えてみてください。そうすれば、あなたの目標を達成するためのスマートな方法を提案できるかもしれません。