Spring AOPとAspectJを比較する
1前書き
今日利用可能なAOPライブラリーは複数ありますが、これらはいくつかの質問に答えることができる必要があります。
-
既存のアプリケーションまたは新しいアプリケーションと互換性がありますか?
-
AOPはどこに実装できますか?
-
それは私のアプリケーションとどのくらい迅速に統合されますか?
-
パフォーマンスのオーバーヘッドは?
この記事では、これらの質問への回答を見ながら、Spring AOPとAspectJ(Java用の2つの最も人気のあるAOPフレームワーク)を紹介します。
2 AOPの概念
始める前に、用語と中心的な概念について簡単に概要を説明しましょう。
-
アスペクト –
複数のコードに分散している標準のコード/機能
アプリケーション内の場所であり、通常実際のものとは異なります。
ビジネスロジック(トランザクション管理など)各側面
特定の分野横断的な機能に焦点を当てています
Joinpoint –
** プログラムの実行中は特別なポイントです
メソッドの実行、コンストラクタの呼び出し、フィールドの割り当てなど
** アドバイス – 特定のジョインポイントでアスペクトによって取られた行動
-
Pointcut – ジョインポイントと一致する正規表現。毎回
任意のジョインポイントはポイントカットと一致します。
そのポイントカットが実行されます
** ウィービング – アスペクトをターゲットオブジェクトとリンクさせるプロセス
アドバイス付きオブジェクトを作成する
3 Spring AOPとAspectJ
さて、Spring AOPとAspectJについて、機能、目標、製織、内部構造、結合点、そして簡潔さなど、さまざまな観点から説明しましょう。
3.1. 機能と目標
簡単に言えば、Spring AOPとAspectJには異なる目標があります。
Spring AOPは、プログラマーが直面する最も一般的な問題を解決するために、Spring IoC全体に単純なAOP実装を提供することを目的としています。
これは完全なAOPソリューションとしての使用を意図したものではありません
– それはSpringコンテナによって管理されるbeanにのみ適用することができます。
一方、
AspectJは、完全なAOPソリューションを提供することを目的としたオリジナルのAOPテクノロジです。
Spring AOPよりも堅牢ですが、かなり複雑です。 AspectJをすべてのドメインオブジェクトに適用できることも注目に値します。
3.2. ウィービング
AspectJとSpring AOPはどちらも、パフォーマンスと使いやすさに関する行動に影響を与えるさまざまな種類のウィービングを使用しています。
AspectJは3種類の織り方を利用します。
-
コンパイル時のウィービング
:AspectJコンパイラは入力として両方の
私たちのアスペクトと私たちのアプリケーションのソースコードと編まれたクラスを生成します
出力としてのファイル
。
ポストコンパイルウィービング
:これはバイナリウィービングとしても知られています。それは
既存のクラスファイルとJARファイルを私たちのアスペクトで織り込むために使用
。
ロードタイムウィービング
:これは以前のバイナリウィービングとまったく同じです。
クラスローダーがクラスファイルをJVMにロードするまで、ウィービングは延期されるという違い
AspectJ自体に関するより詳細な情報については、/aspectjをリンクしてください。
AspectJはコンパイル時とクラスロード時のウィービングを使用するので、
Spring AOPはランタイムウィービング
を利用します。
ランタイムウィービングを使用すると、JDK動的プロキシまたはCGLIBプロキシのいずれかを使用して、ターゲットオブジェクトのプロキシを使用してアプリケーションの実行中にアスペクトが織り込まれます。
リンク:/uploads/springaop-process.png%201279w[]
** 3.3. 内部構造とその応用
Spring AOPはプロキシベースのAOPフレームワークです。つまり、ターゲットオブジェクトにアスペクトを実装するには、そのオブジェクトのプロキシを作成します。これは、2つの方法のいずれかを使用して達成されます。
-
JDK動的プロキシ – Spring AOPには好ましい方法です. いつでも
ターゲットオブジェクトは1つのインタフェースでさえ実装し、その後JDK動的プロキシ
使用されます
。 CGLIBプロキシ – ターゲットオブジェクトがインターフェースを実装していない場合
それからCGLIBプロキシを使用できます
Spring AOPプロキシの仕組みについての詳細はhttps://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop-proxying[公式のドキュメント]をご覧ください。
一方、AspectJは、クラスがアスペクトで直接コンパイルされるため、実行時には何もしません。
そのため、Spring AOPとは異なり、デザインパターンを必要としません。コードにアスペクトを織り込むために、AspectJコンパイラ(ajc)と呼ばれるコンパイラを導入し、それを通してプログラムをコンパイルしてから、小さい(<100K)ランタイムライブラリを提供して実行します。
** 3.4. ジョインポイント
セクション3.3では、Spring AOPがプロキシパターンに基づいていることを示しました。
このため、対象となるJavaクラスをサブクラス化し、それに応じて分野横断的な懸念を適用する必要があります。
しかしそれには限界があります。オーバーライドできないため、実行時例外が発生する可能性があるため、「最終的」なクラスに横断的な懸念(またはアスペクト)を適用することはできません。
静的メソッドと最終メソッドにも同じことが当てはまります。それらをオーバーライドすることはできないため、Springの側面を適用することはできません。したがってSpring AOPはこれらの制限のため、メソッド実行のジョインポイントのみをサポートします。
しかし、AspectJは実行前に横断的な懸念を直接実際のコードに織り込みます。サポートされているジョインポイントの概要は次のとおりです。
| =================================================== = | Joinpoint | Spring AOPサポート| AspectJサポート|メソッド呼び出し|いいえ|はい|メソッド実行|はい|はい|コンストラクタ呼び出し|いいえ|はい|コンストラクタ実行|いいえ|はい|静的イニシャライザ実行|いいえ|はい|オブジェクト初期化|いいえ|はい|フィールド参照|いいえ|はい|フィールド割り当て|いいえ|はい|ハンドラーの実行|いいえ|はい|アドバイスの実行|いいえ|はい| ================== ===================================
Spring AOPでは、同じクラス内で呼び出されるメソッドにアスペクトが適用されていないことも注目に値します。
これは明らかに、同じクラス内のメソッドを呼び出したときに、Spring AOPが提供するプロキシのメソッドを呼び出していないためです。
この機能が必要な場合は、別のBeanに別のメソッドを定義するか、AspectJを使用する必要があります。
3.5. 単純さ
Spring AOPは明らかに単純です。ビルドプロセスの間に余分なコンパイラやウィーバーを導入することはないからです。ランタイムウィービングを使用するため、通常のビルドプロセスとシームレスに統合されます。
それは単純に見えますが、それはSpringによって管理されているbeanでのみ機能します。
ただし、AspectJを使用するには、AspectJコンパイラ(ajc)を導入し、すべてのライブラリを再パッケージする必要があります(ポストコンパイルまたはロード時のウィービングに切り替えない限り)。
もちろん、これは前者よりも複雑です。これは、AspectJ Javaツール(コンパイラ(ajc)、デバッガ(ajdb)、ドキュメンテーションジェネレータ(ajdoc)、プログラム構造ブラウザ(ajbrowser)を含みます)を導入しているからです。 IDEかビルドツールのどちらかと統合する必要があります。
3.6. パフォーマンス
パフォーマンスに関しては、** コンパイル時の製織はランタイムの製織よりはるかに高速です。 Spring AOPはプロキシベースのフレームワークなので、アプリケーションの起動時にプロキシが作成されます。また、アスペクトごとにさらに2、3のメソッド呼び出しがあり、これはパフォーマンスに悪影響を及ぼします。
一方、AspectJはアプリケーションが実行される前にアスペクトをメインコードに織り込むので、Spring AOPとは異なり、追加のランタイムオーバーヘッドはありません。
これらの理由から、https://web.archive.org/web/20150520175004/https://docs.codehaus.org/display/AW/AOPベンチマーク[ベンチマーク]によると、AspectJはおよそ8倍から35倍速いという春のAOP
4概要
この簡単な表は、Spring AOPとAspectJの主な違いをまとめたものです。
| =================================================== ==================== | Spring AOP | AspectJ |ピュアJavaで実装| Javaプログラミング言語の拡張機能を使って実装
|個別のコンパイル・プロセスは不要| LTWがセットアップされていない限り、AspectJコンパイラー(ajc)が必要
|ランタイム・ウィービングのみが使用可能です|ランタイム・ウィービングは使用できません。コンパイル時、ポストコンパイル時、ロード時のウィービングをサポート
|より強力 – メソッドレベルのウィービングのみをサポート|もっと強力 – フィールド、メソッド、コンストラクタ、静的初期化子、最終クラス/メソッドなどを織り込むことができます…
| Springコンテナーによって管理されるBeanにのみ実装できます|すべてのドメイン・オブジェクトに実装できます
|メソッド実行ポイントカットのみをサポート|すべてのポイントカットをサポート
|ターゲット・オブジェクトからプロキシーが作成され、これらのプロキシーにアスペクトが適用されます|アプリケーションが実行される前(ランタイム前)にアスペクトがコードに直接織り込まれます
| AspectJよりはるかに遅い|より良いパフォーマンス
|学びやすく、適用しやすい| Spring AOPよりも比較的複雑| ====================================== ==================================
5正しいフレームワークの選択
このセクションで行われたすべての議論を分析すると、1つのフレームワークが他のフレームワークより優れているとは限らないことを理解し始めます。
簡単に言えば、その選択は我々の要求に大きく依存します。
-
フレームワーク:アプリケーションがSpringフレームワークを使用していない場合は、
Spring AOPを使用するという考えをやめる以外に選択肢はありません。Spring AOPを使用しても、Springコンテナの手の届かないところにあるものは管理できないからです。
しかし、私たちのアプリケーションが完全にSpringフレームワークを使って作成されているならば、
それから、Spring AOPを学び、適用するのが簡単なので、それを使うことができます。
** 柔軟性:限られた参加ポイントのサポートを考えると、Spring AOPはaではありません
完全なAOPソリューションですが、最も一般的な問題を解決します。
プログラマーは直面しています。 AOPをさらに深く掘り下げて活用したいのであれば
その最大の能力と幅広い範囲からのサポートを望んでいる
利用可能なジョインポイントは、AspectJが選択です
** パフォーマンス:限られた側面を使用しているのであれば、ささいなことがあります
パフォーマンスの違いしかし時々ある場合があります
アプリケーションには何万もの側面があります。しない
そのような場合はランタイムウィービングを使用したいので、選択することをお勧めします。
AspectJのため。 AspectJはSpring AOPよりも8倍から35倍速いことが知られています。
** 両方の長所:これらのフレームワークは両方ともそれぞれ完全に互換性があります。
その他可能であればいつでもSpring AOPを利用することができますが、AspectJを使用して前者ではサポートされていないジョインポイントをサポートします
6. 結論
この記事では、Spring AOPとAspectJの両方をいくつかの重要分野で分析しました。
AOPに対する2つのアプローチを、柔軟性と、アプリケーションへの適合性の観点から比較しました。