3

AOPに関する記事に出くわしました。そこでは、アスペクトウィービングは、コンパイル時、クラスのロード時、および実行時に発生する可能性があると述べられています。

Javaでは、コンパイル時にアスペクトウィービングが実際にどのように発生するかを想像することができました。プロキシクラスは、クラスのコンパイル自体の間に生成されます(プロジェクトでアスペクトが有効になっています)。生成されたバイトコードにはプロキシコードが含まれます。

しかし、クラスの読み込み時間の織り方と実行時の織り方の間に、正確に(実際に)何が起こるのかまだ疑問に思っています。クラスのロード中にプロキシクラスが生成されますか?アスペクトライブラリは、プロキシクラス生成のために.class(コンパイル中)ファイルにプログラム命令を追加しますか?

4

3 に答える 3

6

Spring AOPは、実際にはインターフェースにJava動的プロキシーを使用し、必要に応じて、非インターフェース型にはcglibを使用します。SpringBeansでのみ機能します。プロキシは、いわゆるポイントカットと一致するすべてのメソッドに対して自動的に生成されます。これは配線中に行われます。

ただし、 AspectJはプロキシを必要とせず、使用することもありません。既存のバイトコードに組み込まれたバイトコードを直接生成します。AspectJははるかに強力で、メソッドのインターセプト以上のことを実行できます。

  • コンパイル時ウィービング(CTW)の場合、これはAspectJコンパイラajcによって実行されます。ネイティブのAspectJ構文(Javaのスーパーセット)の代わりに、@AspectJ構文と呼ばれることが多いアスペクトを定義するJavaアノテーションスタイルの方法を使用することもできます。この場合、javacを使用してアスペクトをコンパイルし、別のビルドステップでアスペクトウィーバーを使用できます。結果は基本的に同じです。どちらの場合も、実行時にアスペクトが期待どおりに機能するためには、小さなAspectJランタイムライブラリが必要です。
  • CTWとLTW(ロード時ウィービング)の違いは、ウィービングステップがクラスロード時間まで延期されることです。これを機能させるには、JVMコマンドラインにAspectJウィーバーと呼ばれるJavaエージェントライブラリが必要です。Javaエージェントは、通常のアプリケーションクラスがロードされる前に開始されるため、クラスのロードに影響を与え、ロードされたバイトコードを必要に応じてインストルメント化できます。このアプローチは、プロファイリングツールなどでも使用されます。
  • したがって、明らかにLTWはソースコードではなくクラスファイルで動作します。つまり、AspectJはそのアスペクトコードを通常のJavaクラスファイルに織り込むことができます。これは、実行前に実行することもできます。つまり、ソースコードがない外部ライブラリにアスペクトコードを織り込み、ライブラリが読み込まれるたびにLTWの時間を節約するために、新しい変更バージョンを作成できます。 。これはしばしばバイナリ織りと呼ばれます。ある程度の知識があれば、アスペクトコードをJDKに組み込むこともできます。つまり、アスペクトコードを含む変更されたrt.jarを作成することもできます。しかし、これはあなたが通常行うことではありません。私はそれが可能であることを述べたかっただけです。
于 2014-05-13T10:32:23.617 に答える
2

必ずしもコンパイル時ではありません。Javaでは、リフレクションとクラスローダーを使用して、プログラムで実行時にcreateメソッドとクラスを表示および変更することができます。

たとえば、 "hello".getClass().getMethod("substring", Integer.TYPE).invoke("my sharona", 3) 「sharona」を返し、Stringインスタンスからメソッドのサブ文字列を抽出し、それを別のオブジェクトに適用します。

カスタムクラスローダーを使用して、クラスがシステムからどのようにロードされるかを定義できます。このようにして、クラスのバイトコードをロード(または生成)するために呼び出されるメソッドを定義できます。システムクラスローダーを使用して、クラスのバイトコードをロードして検査することもできます。

この手法は、コンパイルされたJavaScriptをJavaバイトコードとしてロードして効率を高めるMozilla Rhino、または実行時にクラス、メソッド、フィールドなどを作成できるJavAssistで広く使用されています。

また、JBossやTomCatなどのアプリケーションサーバーは、リフレクションを使用して、特にアノテーションを介してコードを検査および操作します。

于 2012-12-08T20:28:50.220 に答える
1

実行時の織りが何であるかわからない。ロード時のウィービングでは、エージェントはクラスのロードをインターセプトし、バイトコードを変更してからクラスローダーに渡します。

これがどのように機能するかを確認するのは非常に簡単です。たとえば、AspectJを使用します。コンパイル時のウィービングを使用してコードを分解し、それがどのように機能するかを正確に確認できます。AspectJは、ロード時のウィービング中に生成されたクラスをディスクに保存するように指示することもできます。

于 2012-12-08T20:38:39.153 に答える