アスペクト指向プログラミングの概念と Spring AOP を学んでいます。Pointcut と Joinpoint の違いを理解できていません。どちらも同じように思えます。Pointcut はあなたのアドバイスを適用する場所であり、Joinpoint は私たちのアドバイスを適用できる場所でもあります。では、違いは何ですか?
ポイントカットの例は次のとおりです。
@Pointcut("execution(* * getName()")
ジョインポイントの例は何ですか?
アスペクト指向プログラミングの概念と Spring AOP を学んでいます。Pointcut と Joinpoint の違いを理解できていません。どちらも同じように思えます。Pointcut はあなたのアドバイスを適用する場所であり、Joinpoint は私たちのアドバイスを適用できる場所でもあります。では、違いは何ですか?
ポイントカットの例は次のとおりです。
@Pointcut("execution(* * getName()")
ジョインポイントの例は何ですか?
ジョインポイント:ジョインポイントは、アスペクトをプラグインできるアプリケーションのプログラム実行の候補ポイントです。このポイントは、メソッドが呼び出されたり、例外がスローされたり、フィールドが変更されたりする可能性があります。これらは、アスペクトのコードをアプリケーションの通常のフローに挿入して、新しい動作を追加できるポイントです。
アドバイス:これは、ポイントによって指定されたジョインポイントで実行するアクションを表す、システム全体の懸念への API 呼び出しを含むオブジェクトです。
ポイントカット:ポイントカットは、関連付けられたアドバイスを適用する必要があるジョインポイントを定義します。アドバイスは、AOP フレームワークでサポートされている任意のジョインポイントに適用できます。もちろん、考えられるすべてのジョインポイントですべてのアスペクトを適用したくはありません。ポイントカットを使用すると、アドバイスを適用する場所を指定できます。多くの場合、明示的なクラス名とメソッド名を使用するか、一致するクラス名とメソッド名のパターンを定義する正規表現を使用して、これらのポイントカットを指定します。一部の AOP フレームワークでは、メソッド パラメーターの値など、実行時の決定に基づいてアドバイスを適用するかどうかを決定する動的なポイントカットを作成できます。
次の図は、アドバイス、ポイントカット、ジョインポイントを理解するのに役立ちます。
レストランのアナロジーを使用した説明: @Victor によるソース
レストランに行くと、メニューを見て、いくつかの選択肢から選ぶことができます。メニューにあるアイテムを 1 つまたは複数注文できます。しかし、実際に注文するまでは、あくまでも「食べるチャンス」です。注文してウェイターがテーブルに持ってきたら、それは食事です。
ジョインポイントはメニューのオプションで、ポイントカットは選択した項目です。
ジョインポイントは、側面を適用するためのコード内の機会です...単なる機会です。その機会を利用して、1 つまたは複数のジョインポイントを選択し、それらにアスペクトを適用すると、ポイントカットが得られます。
ソースウィキ:
ジョインポイントは、制御フローが2つの異なるパスを介して到達できるプログラムの制御フロー内のポイントです(IMO:それがジョイントを呼び出す理由です)。
アドバイスは、他の関数を変更する関数のクラスを記述します
ポイントカットは、ジョインポイントの一致するパターン、つまりジョインポイントのセットです。
結合点とポイントカットの違いを理解するには、ポイントカットをウィービング規則を指定するものと考え、結合点をそれらの規則を満たす状況と考えてください。
以下の例では、
@Pointcut("execution(* * getName()")
Pointcut は、どのパッケージのどのクラスにも存在する getName() メソッドにアドバイスを適用する必要があり、joinpoints は、これらのメソッドにアドバイスを適用できるように、クラスに存在するすべての getName() メソッドのリストになるという規則を定義します。
(Spring の場合、ルールはマネージド Bean にのみ適用され、アドバイスはパブリック メソッドにのみ適用できます)。
JoinPoints:これらは基本的に、実際のビジネス ロジックの一部ではなく、必要なさまざまな機能を挿入する実際のビジネス ロジック内の場所です。JoinPints の例としては、メソッド呼び出し、メソッドが正常に戻る、例外をスローするメソッド、オブジェクトのインスタンス化、オブジェクトの参照などがあります。
ポイントカット:ポイントカットは、ジョインポイントを識別するために使用される正規表現のようなものです。ポンカットは「ポイントカット表現言語」で表現されます。ポイントカットは、分野横断的な懸念を適用する必要がある実行フローのポイントです。ジョインポイントとポイントカットには違いがあります。ジョインポイントはより一般的であり、クロスカッティング コンサーンを「導入することを選択できる」制御フローを表し、ポイントカットは、クロスカッティング コンサーンを「導入したい」ジョインポイントを識別します。
AspectJ のような AOP 言語を SQL のようなデータクエリ言語と比較すると、
ドキュメントに従って:
結合ポイント:メソッドの実行や例外処理など、プログラムの実行中のポイント。
ジョイント ポイントは、プログラムの実行におけるイベントと見なすことができます。Spring AOP を使用している場合、これはメソッドの呼び出しに限定されます。AspectJ はより柔軟です。
しかし、レストランに行ったときにメニューのすべての食べ物を食べるわけではないので、すべてのイベントを処理することはできません (私はあなたを知りませんが、そうかもしれません! しかし、私は確かに知りません)。したがって、処理するイベントを選択し、それらをどう処理するかを決定します。これがPointcutsです。ドキュメントによると、
Pointcut :結合点に一致する述語。
次に、何をするかをPointcutに関連付けると、そこにAdviceが続きます。ドキュメントによると、
アドバイスはポイントカット式に関連付けられており、ポイントカットに一致する任意の結合ポイントで実行されます。
package com.amanu.example;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
/**
* @author Amanuel Nega on 10/25/16.
*/
class ExampleBussinessClass {
public Object doYourBusiness() {
return new Object();
}
}
@Aspect
class SomeAspect {
@Pointcut("execution(* com.amanu.example.ExampleBussinessClass.doYourBusiness())")
public void somePointCut() {
}//Empty body suffices
@After("somePointCut()")
public void afterSomePointCut() {
//Do what you want to do after the joint point is executed
}
@Before("execution(* *(*))")
public void beforeSomePointCut() {
//Do what you want to do before the joint point is executed
}
}
ExampleBusinessClass
プロキシされた場合、私たちのターゲットです!doYourBusiness()
可能なジョイントポイントですSomeAspect
などの複数の懸念に交差する私たちの側面ですExampleBusinessClass
somePointCut()
は、ジョイント ポイントに一致するポイント カットの定義です。afterSomePointCut()
ジョイントポイントに合わせた弊社ポイントカット後に実施するアドバイスですsomePointCut
doYourBusiness()
beforeSomePointCut()
すべてのメソッド実行に一致するアドバイスでもあります。public
とは異なりafterSomePointCut
、これはインライン ポイント カット宣言を使用します。信じられない場合は、ドキュメントを参照してください。これが役立つことを願っています
どちらもアスペクト指向プログラミングの「場所」に関連しています。
参加ポイントは、AOP でコードを実行できる個別の場所です。たとえば、「メソッドが例外をスローしたとき」。
ポイントカットは、ジョイン ポイントのコレクションです。たとえば、「クラス Foo のメソッドが例外をスローしたとき」。
JoinPoint : Joinpoint は、例外のキャッチ、他のメソッドの呼び出しなど、実行の流れが変更されたプログラム実行のポイントです。
PointCut : PointCut は基本的に、アドバイス (またはコール アスペクト) を配置できる Joinpoints です。
したがって、基本的にPointCuts は JoinPoints のサブセットです。
PointCut()
は注釈です。アドバイスが適用される内でスコープを宣言できます。
代わりに、JoinPointはインターフェースであり、5 つのアドバイスすべてに使用されるパラメーターです。特に@Aroundアドバイスは、ProceedingJoinPoint (JoinPoint の子インターフェース) を適用し、.proceed()
メソッドを提供します。したがって、プログラムを続行させるかどうかを制御できます。その引数を変更することもできます。