目次
1 はじめに
1.1. AOP 関連の概念
Spring の AOP 実装の最下層は上記の動的プロキシ コードをカプセル化することで、カプセル化後は注意が必要な部分のコードを記述するだけで、設定を通じて指定されたターゲットのメソッド拡張が完了します。
AOP の動作を正式に説明する前に、AOP の関連用語を理解する必要があります。一般的に使用される用語は次のとおりです。
- ターゲット: プロキシのターゲット オブジェクト
- プロキシ (proxy): AOP ウィービングによってクラスが拡張された後、結果のプロキシ クラスが生成されます
- ジョインポイント (接続ポイント): いわゆる接続ポイントは、インターセプトされるポイントを指します。Spring では、Spring ではメソッド型の結合ポイントのみがサポートされるため、これらのポイントはメソッドを参照します。
- ポイントカット (エントリ ポイント): いわゆるエントリ ポイントは、インターセプトするジョインポイントの定義を指します。
- アドバイス (通知/拡張): いわゆる通知とは、Joinpoint をインターセプトした後に何をすべきかを通知することを意味します。
- 側面: エントリーポイントと通知の組み合わせです (導入)
- ウィービング (ウィービング): ターゲット オブジェクトに拡張機能を適用して、新しいプロキシ オブジェクトを作成するプロセスを指します。Spring は動的プロキシ ウィービングを使用しますが、AspectJ はコンパイル時のウィービングとクラスの読み込み時のウィービングを使用します。
1.2、AOP開発の明確な事項
1.何を書くか
コア ビジネス コード (ターゲット クラスのターゲット メソッド) を作成します。
アスペクトクラスを書く、アスペクトクラス内に通知がある(拡張機能メソッド)
構成ファイルで、ウィービング関係、つまりどの通知をどの接続ポイントと組み合わせるかを構成します。
2. AOP技術の導入内容
Spring フレームワークは、ポイントカット メソッドの実行を監視します。ポイントカットメソッドが監視されたら、プロキシメカニズムを使用してターゲットオブジェクトを動的に作成します
プロキシ オブジェクトは、通知カテゴリに従って、通知の対応する機能をプロキシ オブジェクトの対応する位置に織り込み、完全なコード ロジック操作を完了します。
3. AOP の下部でどのプロキシ メソッドが使用されているか
Spring では、フレームワークは、ターゲット クラスがインターフェイスを実装しているかどうかに応じて、どの動的プロキシ メソッドを使用するかを決定します。
1.3. 重要な知識のポイント
- aop: アスペクト指向プログラミング
- aop の基礎となる実装: JDK に基づく動的プロキシと Cglib に基づく動的プロキシ
- AOP の主要な概念:
-
- ポイントカット: 強化された方法
- アドバイス(通知・拡張):拡張されたビジネスロジックのカプセル化方法
- Aspect(アスペクト):カットポイント+通知
- ウィービング: ポイントカットとアドバイスを組み合わせるプロセス
- 開発特有の問題:
-
- ポイントカットは誰ですか (ポイントカット式の構成)
- 通知は誰ですか (アスペクト クラスの拡張メソッド)
- ポイントカットとアドバイスを構成に織り込む
2. 2つの方法
AOP (Aspect-Oriented Programming、アスペクト指向プログラミング) 開発は、プログラムによるものと宣言的なものという 2 つの主な方法で実現できます。これら 2 つの方法は、アスペクト ロジックをコードに直接記述する方法と、特定の構成を使用してアスペクト ロジックを記述する 2 つの異なる方法に対応します。
- プログラムによる AOP:プログラムによる AOP とは、アスペクト ロジックをコード内に直接記述することを指します。このアプローチでは、開発者は、通常はメソッド呼び出しを通じて、コード内でアスペクト ロジックを明示的に呼び出す必要があります。プログラムによる AOP は非常に高い柔軟性を提供し、開発者はアスペクト ロジックの適用タイミングを正確に制御できますが、コードの冗長性や保守性の低下につながる可能性があります。
- 宣言型 AOP:宣言型 AOP は、コード内でアスペクト ロジックを明示的に呼び出すことなく、特定の構成を使用してアスペクト ロジックを記述することを指します。この方法では、アプリケーションのタイミングとアスペクト ロジックのルールを構成ファイルまたはアノテーションを使用して定義します。宣言型 AOP は、保守性とコードのモジュール化を向上させ、アスペクト ロジックをメインのビジネス ロジックから分離し、コードの可読性と保守性を向上させます。
宣言型 AOP には、次の 2 つの一般的なアプローチがあります。
- XML ベースの構成: XML を使用して、Spring AOP の XML 構成などの構成ファイル内のアスペクト ロジックのウィービング タイミングとルールを記述します。
- 注釈ベース: Spring AOP の注釈ベースのアプローチなど、注釈を使用してアプリケーションのタイミングとアスペクト ロジックのルールをマークします。
どちらのアプローチにも独自の利点があり、どちらを選択するかは、プロジェクトの要件とチームの好みによって異なります。プログラムによる AOP は柔軟性が高く、一部の特定のシナリオに適しています。宣言型 AOP は可読性と保守性が向上し、ほとんどのプロジェクトに適しており、横断的な関心事の分離と処理をより適切に実現できます。
以下では、2 種類の宣言型 AOP に焦点を当てます。
3. XMLに基づく
3.1. クイックスタート
基本的な手順は次のとおりです。
①AOP関連座標のインポート
② ターゲットインターフェースとターゲットクラスの作成(内部カットポイント)
③ アスペクトクラスの作成(内部拡張メソッドを使用)
④対象クラスとアスペクトクラスのオブジェクト作成権限をSpringに渡す
⑤applicationContext.xmlにウィービング関係を設定する
⑥テストコード
全体のディレクトリは次のとおりです。
3.1.1. 座標のインポート
<!--导入aop相关坐标--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> </dependency> <!--spectj の入力 --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency>
3.1.2、インターフェースと実装クラスの作成
3.1.3. ファセットの作成
3.1.4、Beanの構成
3.1.5. 構成ウィービング
3.1.6. テスト
3.2. ポイントカット式
式の構文:
実行([修飾子] 戻り値の型 パッケージ名.クラス名.メソッド名(パラメータ))
アクセス修飾子は省略可能
戻り値の型、パッケージ名、クラス名、およびメソッド名には、アスタリスク * を使用して任意の値を表すことができます。
パッケージ名とクラス名の間のドット。現在のパッケージの下のクラスを表します。2 つのドット。現在のパッケージとそのサブパッケージの下のクラスを表します。
パラメータ リストでは 2 つのドットを使用して、任意の数および任意のタイプのパラメータ リストを表すことができます。
3.2.1. 式の例
例:
実行(public void com.itheima.aop.Target.method())
実行(void com.itheima.aop.Target.*(..))
実行(* com.itheima.aop.*.*(..))
実行(* com.itheima.aop..*.*(..))
実行(* *..*.*(..))
以下では、これらのポイントカット式の意味を順番に説明します。
- 実行(public void com.itheima.aop.Target.method()):
-
- com.iheima.aopパッケージのTargetクラスのメソッドメソッドと一致します。
- このメソッドの修飾子はpublic、戻り値の型はvoidで、パラメータを受け入れません。
- 特定のクラス、メソッド、およびパラメーターのみが一致することを示します。
- 実行(void com.itheima.aop.Target.*(..)):
-
- com.iheima.aopパッケージのTargetクラスのメソッドと一致します。
- このメソッドの修飾子には制限がなく、戻り値の型はvoidです。
- (..) は、メソッドが任意の数とタイプのパラメータを受け入れることができることを示します。
- 実行(* com.itheima.aop.*.*(..)):
-
- com.iheima.aopパッケージ内の任意のクラスの任意のメソッドと一致します。
- メソッド修飾子、戻り値の型、パラメータには制限がありません。
- 実行(* com.itheima.aop..*.*(..)):
-
- com.iheima.aopパッケージおよびそのサブパッケージ内の任意のクラスの任意のメソッドと一致します。
- メソッド修飾子、戻り値の型、パラメータには制限がありません。
- 実行(* *..*.*(..)):
-
- 任意のパッケージの任意のクラスの任意のメソッドと一致します。
- メソッド修飾子、戻り値の型、パラメータには制限がありません。
- ワイルドカード*..*は、任意のパッケージ名とサブパッケージを表します。
これらのポイントカット式は、異なる範囲のクラスやメソッドを照合するために使用され、ニーズに応じて最適な式を選択できます。AOPでは、ポイントカッティング式を用いてアスペクトロジックの適用タイミングを指定し、横断的な関心事の処理を実現します。
3.2.2、式の抽出
複数の拡張ポイントカット表現が同じである場合、それらのポイントカット表現を抽出することができ、抽出されたポイントカット表現を参照するために拡張の pointcut 属性の代わりに pointcut-ref 属性が使用されます。
3.3. 通知の種類
3.3.1. 通知とは
アドバイス:アドバイスはアスペクトの特定の動作であり、接続ポイントでどのロジックを実行するかを決定します。
通常、通知には次のタイプがあります: 事前通知 (Before)、事後通知 (After)、リターン通知 (AfterReturning)、例外通知 (AfterThrowing)、およびサラウンド通知 (Around)。
アドバイス (Advice) は、AOP の中核概念の 1 つであり、特定の接続ポイント (メソッド呼び出し、オブジェクトのインスタンス化など) で実行されるアスペクト ロジックを表します。アドバイスは、結合ポイントで特定のアクションがいつ、どのように実行されるかを決定します。AOP は、横断的な関心事の分離を達成するために、さまざまな実行時間でアスペクト ロジックを適用するためのさまざまな種類のアドバイスを提供します。
AOP で一般的に使用されるさまざまな種類のアドバイスを次に示します。
- Before Advice (Before Advice):プレアドバイスはターゲットメソッドの実行前に実行されます。通常、権限チェックやパラメータ検証などのいくつかの準備操作を実行するために使用されます。
- アドバイス後:ターゲット メソッドが例外をスローするかどうかに関係なく、ターゲット メソッドの実行後にアドバイス後が実行されます。リソースの解放やロギングなどの操作によく使用されます。
- アドバイスを返した後: アドバイスを返した後は、ターゲット メソッドが正常に実行され、 result を返した後に実行されます。対象メソッドの戻り値を取得し、それに応じた処理を行うことができます。
- アドバイスのスロー後:アドバイスのスロー後は、ターゲット メソッドが例外をスローしたときに実行されます。これを使用して、例外をキャッチして処理したり、例外関連の操作を実行したりできます。
- アラウンド アドバイス: アラウンド アドバイスは、最も強力で柔軟なタイプのアドバイスです。メソッドの前後のカスタム操作を含め、ターゲット メソッドの実行プロセスを完全に制御でき、ターゲット メソッドを呼び出すかどうかを選択できます。
これらの通知タイプにより、開発者はビジネス ニーズに応じてさまざまな実行時間でアスペクト ロジックを追加できます。さまざまなタイプの通知を組み合わせることで、ロギング、トランザクション管理、セキュリティチェックなど、アプリケーションのさまざまなレベルで横断的な問題に対処できます。通知は AOP の中核要素の 1 つであり、これによりアスペクト ロジックを適切なタイミングでターゲット コードに組み込むことができるため、コードの分離とモジュール化が実現します。
3.3.2. 設定方法
通知タイプ |
XML構成例 |
事前通知(Before) |
|
通知後(後) |
|
返却通知(返却後) |
|
例外通知 (AfterThrowing) |
|
アラウンド通知(アラウンド) |
|
4. アノテーションベース
4.1. クイックスタート
アノテーションベースの AOP 開発手順:
① ターゲットインターフェースとターゲットクラスの作成(内部カットポイント)
② アスペクトクラスの作成(内部拡張メソッドを使用)
③対象クラスとアスペクトクラスのオブジェクト作成権限をSpringに渡す
④アノテーションを利用してアスペクトクラスに織り込み関係を設定する
⑤ 設定ファイルでコンポーネントのスキャンと AOP の自動プロキシを有効にする
⑥テスト
ディレクトリは次のとおりです。
4.1.1. インターフェースと実装クラスの作成
4.1.2. ファセットの作成
4.1.3、Beanの構成
この時点のアスペクト クラスは単なる通常の Bean であり、後続の構成が必要です。
4.1.4、構成ウィービング
4.1.5、コンポーネントのスキャンと自動プロキシ
4.1.6. テスト
4.2. アノテーション通知タイプ
通知設定構文: @notification アノテーション( "pointcutexpression" )
通知タイプ |
注釈 |
説明する |
予告 |
@前に |
拡張メソッドがポイントカット メソッドの前に実行されることを指定します。 |
通知を投稿する |
@AfterReturning |
拡張メソッドがポイントカットメソッドの後に実行されることを指定します |
サラウンド通知 |
@その周り |
拡張メソッドがポイントカット メソッドの前後の両方で実行されることを指定します。 |
スローされた例外通知 |
@AfterThrowing |
例外が発生したときに拡張メソッドが実行されることを指定します |
最終通告 |
@後 |
拡張メソッドの実行で例外が発生したかどうかに関係なく実行されます |
4.3、式の抽出
XML 設定 AOP と同様に、ポイントカット式を抽出できます。
抽出方法は、アスペクト内でメソッドを定義し、@Pointcutアノテーションを使用してメソッド上にポイントカット式を定義し、拡張アノテーションで参照する方法です。
詳細は次のとおりです。