私はアスペクト指向プログラミングの概念とSpring AOPを学んでいます。ポイントカットとジョインポイントの違いを理解できていません-両者は同じように見えます。ポイントカットはアドバイスを適用する場所であり、ジョインポイントはアドバイスを適用できる場所でもあります。それでは違いは何ですか?
ポイントカットの例は次のとおりです。
@Pointcut("execution(* * getName()")
ジョインポイントの例は何ですか?
Joinpoint:ジョインポイントは、プログラム内のcandidateポイントですアスペクトをプラグインできるアプリケーションの実行。このポイントは、呼び出されるメソッド、スローされる例外、または修正されるフィールドである可能性があります。これらは、新しい動作を追加するために、アプリケーションの通常のフローにアスペクトのコードを挿入できるポイントです。
Advice:これは、ポイントで指定されたジョインポイントで実行するアクションを表すシステム全体の懸念に対するAPI呼び出しを含むオブジェクトです。
ポイントカット:ポイントカットは、どのジョインポイントで、関連するアドバイスが適用されるべきかを定義します。アドバイスは、AOPフレームワークでサポートされている任意のジョインポイントで適用できます。もちろん、可能なすべての参加ポイントですべての側面を適用したくはありません。ポイントカットを使用すると、アドバイスを適用する場所を指定できます。多くの場合、これらのポイントカットは、明示的なクラス名とメソッド名を使用するか、一致するクラス名とメソッド名のパターンを定義する正規表現を使用して指定します。一部のAOPフレームワークでは、メソッドパラメータの値など、実行時の決定に基づいてアドバイスを適用するかどうかを決定する動的ポイントカットを作成できます。
次の画像は、Advice、PointCut、Joinpointsを理解するのに役立ちます。
レストランの類推を使用した説明:Source by @Victor
レストランに出かけるときは、メニューを見て、選択できるいくつかのオプションを確認します。メニューの任意のアイテムを1つ以上注文できます。しかし、実際に注文するまでは、「食事をする機会」にすぎません。注文してウェイターがあなたのテーブルに持ってきたら、それは食事です。
Joinpointsはメニューのオプションで、Pointcutsは選択した項目です
ジョインポイントは、アスペクトを適用するためのコード内の機会です...ただの機会です。その機会を利用して1つ以上のジョインポイントを選択し、それらにアスペクトを適用すると、ポイントカットが得られます。
結合ポイントとポイントカットの違いを理解するには、ポイントカットをウィービングルールを指定するものと考え、結合ポイントをそれらのルールを満たす状況として考えます。
以下の例では、
@Pointcut("execution(* * getName()")
Pointcutは、アドバイスを任意のパッケージの任意のクラスに存在するgetName()メソッドに適用し、joinpointsはクラスに存在するすべてのgetName()メソッドのリストになるため、これらのメソッドにアドバイスを適用できるというルールを定義します。
(Springの場合、ルールはマネージドBeanにのみ適用され、アドバイスはパブリックメソッドにのみ適用できます)。
JoinPoints:これらは、実際のビジネスロジックの一部ではなく、必要なその他の機能を挿入する実際のビジネスロジックの基本的な場所です。 JoinPintsのいくつかの例は次のとおりです。メソッド呼び出し、通常に戻るメソッド、例外をスローするメソッド、オブジェクトのインスタンス化、オブジェクトの参照など。
ポイントカット:ポイントカットは、ジョインポイントを識別するために使用される正規表現のようなものです。ポンカットは、「ポイントカット表現言語」を使用して表現されます。ポイントカットは、横断的な関心事を適用する必要がある実行フローのポイントです。 JoinpointとPointcutには違いがあります。ジョインポイントはより一般的であり、横断的な関心事を「選択する可能性のある」制御フローを表し、ポイントカットは横断的な関心事を導入する「そのような」ジョインポイントを識別します。
AOPの概念に慣れていない人のためのレイマンの説明。これは網羅的なものではありませんが、概念を理解するのに役立つはずです。すでに基本的な専門用語に精通している場合は、今すぐ読むのをやめることができます。
通常のクラスEmployeeがあり、これらのメソッドが呼び出されるたびに何かをしたいとします。
class Employee{
public String getName(int id){....}
private int getID(String name){...}
}
これらのメソッドはJoinPointsと呼ばれます。フレームワークがロードしたすべてのclasses.methodsの中からメソッドを見つけることができるように、これらのメソッドを識別する方法が必要です。したがって、これらのメソッドのシグネチャに一致する正規表現を作成します。以下に示すように、さらに多くの機能がありますが、大まかに言って、この正規表現はPointcutを定義するものです。例えば.
* * mypackage.Employee.get*(*)
最初の*は修飾子public/private/protected/default用です。 2番目の*は、メソッドの戻り値の型です。
ただし、さらに2つのことを伝える必要があります。
これら2つの組み合わせはAdviceと呼ばれます。
ご想像のとおり、#2を実行するには関数を作成する必要があります。したがって、これは基本的にどのように見えるかです。
注:明確にするために、* * mypackage.Employee.get*(*)
の代わりにWordREGEXを使用します。実際には、完全な表現は定義に含まれます。
@Before("execution(REGEX)")
public void doBeforeLogging() {....} <-- executed before the matching-method is called
@After("execution(REGEX)")
public void doAfterLogging() {....} <-- executed after the matching-method is called
これらをかなり使い始めたら、多くの@ After/@ Before/@ Aroundアドバイスを指定することになります。 repeated正規表現は、最終的に物事を混乱させ、維持するのを難しくします。そのため、式に名前を付け、Aspectクラスの他のすべての場所で使用します。
@Pointcut("execution(REGEX)") <-- Note the introduction of Pointcut keyword
public void allGetterLogging(){} <-- This is usually empty
@Before("allGetterLogging")
public void doBeforeLogging() {....}
@After("allGetterLogging")
public void doAfterLogging() {....}
ところで、このロジック全体をクラスにラップすることもできます。これはAspectと呼ばれ、クラスを記述します。
@Aspect
public class MyAwesomeAspect{....}
これらすべてを機能させるには、クラスを解析して@ AOPキーワードを読み取り、理解し、アクションを実行するようにSpringに指示する必要があります。それを行う1つの方法は、spring config xmlファイルで以下を指定することです。
<aop:aspectj-autoproxy>
AspectJのようなAOP言語をSQLのようなデータクエリ言語と比較すると、ジョインポイント(つまり、アスペクトコードを織り込めるコード内のすべての場所)を多数の行を持つデータベーステーブルと考えることができます。ポイントカットは、ユーザー定義の行/結合点のサブセットを選択できるSELECTステートメントのようなものです。選択した場所に織り込む実際のコードは、アドバイスと呼ばれます。
どちらもアスペクト指向プログラミングの「どこ」に関係しています。
結合ポイントは、AOPでコードを実行できる個々の場所です。例えば。 「メソッドが例外をスローしたとき」。
ポイントカットは、結合ポイントのコレクションです。例えば。 「Fooクラスのメソッドが例外をスローしたとき」。
ドキュメントに従って:
Join point:メソッドの実行や例外の処理など、プログラムの実行中のポイント。
Joint Pointsは、プログラムの実行中のイベントと見なすことができます。 Spring AOPを使用している場合、これはメソッドの呼び出しに限定されます。 AspectJはより柔軟性があります。
しかし、レストランに行くときにメニューのすべての食べ物を食べないので、すべてのイベントを処理することはありません(私はあなたを知りません、あなたかもしれません!しかし、私は確かにしません)。そのため、処理するイベントとそれらをどうするかを選択します。 Pointcutsになります。ドキュメントによると、
Pointcut:join pointsと一致する述語。
次に、何をするかをPointcutに関連付け、そこにAdviceを追加します。ドキュメントによると、
Adviceはpointcut式に関連付けられ、pointcutに一致する任意の結合ポイントで実行されます。
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 before 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
メソッドの実行に一致するadviceでもあります。 afterSomePointCut
とは異なり、これはインラインポイントカット宣言を使用しますあなたが私を信じないなら、あなたは documentation を見ることができます。これが役立つことを願っています
JoinPoint:ジョインポイントは、プログラムの実行において、例外のキャッチ、他のメソッドの呼び出しなど、実行のフローが変更されたポイントです。
PointCut:PointCutは基本的に、アドバイスを入力(またはアスペクトを呼び出す)できるJoinpointです。
基本的にPointCutsはJoinPointsのサブセットです。
ポイントカットは、アスペクト-クラス実装で定義されます。ポイントカットは、基本的にアドバイス内のポイントカット式を指します。
たとえば、
@Before("execution(* app.purchase2.service.impl.*(..))")
public void includeAddOns(RolesAllowed roles) {
..
}
上記の意味は、「includeAddOns」メソッドは(@Beforeアドバイスにより)メソッドを呼び出す前に呼び出されます(パッケージ「app.purchase2.service.impl」内のクラス)
注釈全体は、ポイントカット@Before("execution(* app.purchase2.service.impl.*(..))")
と呼ばれます
ジョイントポイントは、パッケージ「app.purchase2.service.impl」のメソッドをアスペクトクラス「includeAddOns()」のメソッドに結合した実際のメソッド呼び出しです。
org.aspectj.lang.JoinPoint
クラスを使用して、結合ポイントのプロパティにアクセスできます。
Mgrovesに同意します。ポイントカットは、複数のジョイントポイントの集合と見なすことができます。ジョイントポイントは、アドバイスを実装できる特定の場所を指定します。ポイントカットは、すべてのジョイントポイントのリストを反映します。
春のAOPには{Advisor、Advice、Pointcut、Joinpoint}があります
ご存じのとおり、aopの主な目的は、横断的な懸念ロジック(アスペクト)をアプリケーションコードから分離し、これを使用するSpring(Advice/Advisor)に実装することです。
Pointcutは、「すべてのメソッドが挿入で始まる」など、このアドバイスを正確に適用したい場所をフィルタリングするために使用されるため、他のメソッドは除外されます。そのため、Pointcutインターフェイス{ClassFilter and MethodMatcher}
そのため、Adviceはクロスカッティングロジックの実装であり、AdvisorはアドバイスとPointCutを組み合わせたものです。アドバイスのみを使用する場合、springはadvisorにマップし、ポイントカットをTRUEにします。そのため、アドバイスのみを使用する場合、ターゲットクラスのすべてのメソッドにフィルターが適用されていないため、それらが適用されます。
しかし、Joinpointはプログラム内の場所であり、Classオブジェクトにアクセスするとリフレクションのように考えることができます。その後、Methodオブジェクトを取得し、このクラスのメソッドを呼び出すことができます。これは、Joinpointを想像できます。
Joinpointはフィールド、コンストラクター、またはメソッドで使用できますが、SpringにはメソッドのみのJoinpointがあります。そのため、Springには(Before、After、Throws、Around)タイプのJoinpointがあり、それらはすべてクラス内の場所を参照します。
先ほど述べたように、ポイントカットなし(フィルターなし)でアドバイスを得ることができ、それはすべてのメソッドに適用されるか、特定のメソッドに適用される[アドバイス+ポイントカット]であるアドバイザーを持つことができます。ジョインポイントはポイントカットのように指定する必要があります。そのため、春のアドバイスタイプはジョインポイントとまったく同じタイプなので、アドバイスを選択するときに暗黙的にどのジョインポイントを選択するのですか。
まとめると、アドバイスは、ターゲットクラスに対するアスペクトの実装ロジックです。このアドバイスには、呼び出し前、呼び出し後、スロー後または呼び出し前後のようなジョインポイントが必要です。その後、ポイントカットを使用して、正確に適用する場所をフィルタリングできますメソッドをフィルター処理するか、ポイントカットなし(フィルターなし)にして、クラスのすべてのメソッドに適用されるようにします。