Spring AOP:JoinPointとPointCutの違いは何ですか?


88

私はアスペクト指向プログラミングの概念とSpring AOPを学んでいます。ポイントカットとジョインポイントの違いを理解できていません。どちらも同じように見えます。ポイントカットはアドバイスを適用する場所であり、ジョインポイントはアドバイスを適用できる場所でもあります。次に、違いは何ですか?

ポイントカットの例は次のとおりです。

@Pointcut("execution(* * getName()")

ジョインポイントの例は何ですか?

回答:


161

ジョインポイント:ジョインポイントは、アスペクトをプラグインできるアプリケーションのプログラム実行の候補ポイントです。このポイントは、メソッドの呼び出し、例外のスロー、またはフィールドの変更である可能性があります。これらは、アスペクトのコードをアプリケーションの通常のフローに挿入して、新しい動作を追加できるポイントです。

アドバイス:これは、ポイントで指定されたジョインポイントで実行するアクションを表す、システム全体の懸念に対するAPI呼び出しを含むオブジェクトです。

ポイントカットポイントカットは、どのジョインポイントに関連するアドバイスを適用するかを定義します。アドバイスは、AOPフレームワークでサポートされている任意の結合点に適用できます。もちろん、考えられるすべてのジョインポイントにすべての側面を適用する必要はありません。ポイントカットを使用すると、アドバイスを適用する場所を指定できます。多くの場合、これらのポイントカットは、明示的なクラス名とメソッド名を使用するか、一致するクラス名とメソッド名のパターンを定義する正規表現を使用して指定します。一部のAOPフレームワークでは、メソッドパラメーターの値などの実行時の決定に基づいてアドバイスを適用するかどうかを決定する動的ポイントカットを作成できます。

次の画像は、アドバイス、ポイントカット、ジョインポイントを理解するのに役立ちます。 ここに画像の説明を入力してください

ソース

Restaurant Analogyを使用した説明: @Victorによるソース

レストランに出かけるときは、メニューを見て、いくつかのオプションから選択します。メニューのアイテムを1つ以上注文できます。しかし、実際に注文するまでは、「食事する機会」に過ぎません。注文すると、ウェイターがそれをあなたのテーブルに持ってきたら、それは食事です。

ジョインポイントはメニューのオプションであり、ポイントカットはユーザーが選択するアイテムです。

ジョインポイントは、アスペクトを適用するためのコード内の機会です...単なる機会です。その機会を利用して1つ以上のジョインポイントを選択し、それらにアスペクトを適用すると、ポイントカットが得られます。

ソースWiki

参加点は、制御フローを介して到着することができ、プログラムの制御フロー内の点である2つの異なるパス(なぜコールジョイントのIMO)。

アドバイスは、他の関数を変更する関数のクラスを記述します

ポイントカットは、参加点の集合です。


3
これは正解としてマークする必要があります。さらに情報を追加するには、Cragi Wallsの回答をご覧ください... coderanch.com/t/485525/Spring/Difference-Joint-Point-Point-Cut
ビクター

2
ポイントに:アドバイスをジョインポイント何でポイントカット定義は+1適用されるべきである
ナマンガラ

確認のためだけに、more Joinpoints and apply an aspect to them, you've got a Pointcut. 彼らへの側面や彼らへのアドバイス?
Asif Mushtaq 2018年

@Premrajだから、アナロジーのアドバイスによると、食事を注文します。私は正しいですか?
Vishwas

レストランのアナロジーは、JoinPointsとポイントカットの混乱を解消するのに役立ちました。
SM

30

ジョインポイントとポイントカットの違いを理解するには、ポイントカットをウィービングルールを指定し、ジョインポイントをそれらのルールを満たす状況として指定することを考えてください。

以下の例では、

  @Pointcut("execution(* * getName()")  

ポイントカットはルールを定義しており、アドバイスはパッケージ内のクラスに存在するgetName()メソッドに適用する必要があり、ジョインポイントはクラスに存在するすべてのgetName()メソッドのリストになるため、これらのメソッドにアドバイスを適用できます。

(Springの場合、ルールはマネージドBeanにのみ適用され、アドバイスはパブリックメソッドにのみ適用できます)。


1
「ポイントカットはルールを定義しており、アドバイスはパッケージ内のクラスに存在するgetName()メソッドに適用する必要があり、ジョインポイントはクラスに存在するすべてのgetName()メソッドのリストになるため、これらのメソッドにアドバイスを適用できます。」申し訳ありませんが、これはさらに混乱します。現実の日常生活のシナリオの例を教えてください。
Saurabh Patil 2013

28

JoinPoints:これらは基本的に、実際のビジネスロジックの一部であり、必要ではないが実際のビジネスロジックの一部ではないその他の機能を挿入する場所です。JoinPintsの例としては、メソッドの呼び出し、正常に戻るメソッド、例外のスロー、オブジェクトのインスタンス化、オブジェクトの参照などがあります。

ポイントカット:ポイントカットは、ジョインポイントを識別するために使用されている正規表現のようなものです。ポンカットは「ポイントカット表現言語」で表現されています。ポイントカットは、横断的関心事を適用する必要がある実行フローのポイントです。ジョインポイントとポイントカットには違いがあります。ジョインポイントはより一般的であり、横断的関心事を「選択」する可能性のある制御フローを表しますが、ポイントカットは、横断的関心事を導入したい結合ポイントを識別します。


1
ジョインポイント-アドバイスコードを適用/実行する潜在的な場所。ポイントカット-アドバイスを実行するために実際に選択された結合点。
user104309 2017年

24

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つのことを伝える必要があります。

  1. ときにアクションが取られるべきである-例えば/前にメソッドの実行後、または例外に
  2. それが一致したときに行う必要があります(おそらく、単にメッセージを印刷します)

これら2つの組み合わせをアドバイスと呼びます。

ご想像のとおり、#2を実行できるようにするには、関数を作成する必要があります。したがって、これは基本的には次のようになります。

注:明確にするために、の代わりにREGEXという単語を使用し* * mypackage.Employee.get*(*)ます。実際には、完全な表現が定義に入ります。

@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アドバイスを指定することになります。繰り返し正規表現は最終的に物事が混乱し、維持するために困難になってしまいます。したがって、実行することは、式に名前を付けて、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構成xmlファイルで以下を指定することです。

<aop:aspectj-autoproxy>


1
私はAOPを初めて使用するので、この説明は、アドバイス/ポイントカット/ジョインポイント間の関係を非常に明確に理解するのに役立ちました。
Jatin Shashoo 2017年

11

AspectJのようなAOP言語をSQLのようなデータクエリ言語と比較すると、ジョインポイント(つまり、アスペクトコードを織り込むことができるコード内のすべての場所)を、多くの行を持つデータベーステーブルと考えることができます。ポイントカットは、行/ジョインポイントのユーザー定義のサブセットを選択できるSELECTステームメントに似ています。これらの選択した場所に織り込む実際のコードは、アドバイスと呼ばれます。


9

定義

ドキュメントに従って:

結合ポイント:メソッドの実行や例外の処理など、プログラムの実行中のポイント。

ジョイントポイントは、プログラムの実行中のイベントと見なすことができます。Spring AOPを使用している場合、これはメソッドの呼び出しに限定されます。AspectJはより高い柔軟性を提供します。

しかし、レストランに行くとき、メニューのすべての食べ物を食べないので、すべてのイベントを処理することはありません(私はあなたを知らないので、あなたはそうかもしれません!したがって、処理するイベントとそれらをどうするかを選択します。ここにポイントカットがあります。ドキュメントに従って、

ポイントカット結合ポイントに一致する述語。

そして、あなたは何を行うに関連付けるポイントカット、そこに行くのアドバイスを。ドキュメントに従って、

アドバイスポイントカット式に関連付けられており、ポイントカットに一致する任意の結合ポイントで実行されます。

コード

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、これはインラインポイントカット宣言を使用します。

信じられない場合は、ドキュメントをご覧ください。これが役に立てば幸い


1
簡単な説明。理解するには、引用された3つのテキストだけで十分です。ありがとう。
TRiNE 2018

6

どちらもアスペクト指向プログラミングの「どこ」に関係しています。

参加ポイントは、AOPでコードを実行できる個別の場所です。たとえば、「メソッドが例外をスローしたとき」などです。

ポイントカットは、結合ポイントのコレクションです。たとえば、「クラスFooのメソッドが例外をスローしたとき」などです。


4

JoinPoint:Joinpointは、例外のキャッチ、他のメソッドの呼び出しなど、実行のフローが変更されたプログラム実行のポイントです。

PointCut:PointCutは基本的に、アドバイス(または呼び出しの側面)を入力できるJoinpointです。

したがって、基本的にはPointCutsはJoinPointsのサブセットです


3

春のAOPには{アドバイザー、アドバイス、ポイントカット、ジョインポイント}があります。

ご存知のように、aopの主な目的は、横断的な関心ロジック(アスペクト)をアプリケーションコードから分離することです。これをSpringで実装するには、次のように使用します(アドバイス/アドバイザー)。

「すべてのメソッドは挿入で始まる」のように、このアドバイスを適用したい場所をフィルタリングするためにポイントカットが使用されるため、他のメソッドは除外されます。そのため、ポイントカットインターフェイス{ClassFilter and MethodMatcher}にあります。

したがって、Adviceは横断的なロジックの実装であり、AdvisorはアドバイスとPointCutです。アドバイスのみを使用する場合、SpringはそれをAdvisorにマップし、ポイントカットをTRUEにして、何もブロックしないようにします。そのため、アドバイスのみを使用すると、フィルター処理を行わなかったため、ターゲットクラスのすべてのメソッドに適用されます。

しかし、Joinpointはプログラム内の場所です。Classオブジェクトにアクセスすると、リフレクションのように考えることができ、次にMethodオブジェクトを取得して、このクラスの任意のメソッドを呼び出すことができます。コンパイラが機能する方法は、次のとおりです。これはジョインポイントを想像できます。

ジョインポイントはフィールド、コンストラクター、またはメソッドで使用できますが、Springではメソッドのみのジョインポイントがあるため、Springでは(Before、After、Throws、Around)タイプのジョインポイントがあり、それらはすべてクラス内の場所を参照します。

ポイントカットなし(フィルターなし)のアドバイスがある場合は、前述のように、すべてのメソッドに適用されます。特定のメソッドに適用される[アドバイス+ポイントカット]のアドバイザーを持つことはできますが、アドバイスなしにはアドバイスできません。 pointcutのようなjoinpointは指定する必要があります。そのため、Springのアドバイスタイプはjoinpointとまったく同じタイプなので、アドバイスを選択すると、暗黙的にどのジョインポイントを選択するかが決まります。

まとめると、アドバイスは、ターゲットクラスに対するアスペクトの実装ロジックです。このアドバイスには、呼び出し前、呼び出し後、スロー後、または呼び出し前後のような結合点が必要です。pointcutを使用して適用する場所を正確にフィルタリングできます。メソッドをフィルタリングするか、ポイントカットなし(フィルターなし)にすることで、クラスのすべてのメソッドに適用されます。


3

ポイントカットは、アスペクト-クラス実装で定義されます。ポイントカットは、基本的にアドバイス内のポイントカット表現を指します。

たとえば、

@Before("execution(* app.purchase2.service.impl.*(..))")
public void includeAddOns(RolesAllowed roles) {
..
}

上記は、(@ Beforeのアドバイスにより)呼び出し前に「includeAddOns」メソッドが呼び出されることを意味します(パッケージ「app.purchase2.service.impl」内のクラス内)

注釈全体はポイントカットと呼ばれます @Before("execution(* app.purchase2.service.impl.*(..))")

ジョイントポイントは、パッケージ「app.purchase2.service.impl」のメソッドをアスペクトクラス「includeAddOns()」のメソッドに結合した実際のメソッド呼び出しです。

org.aspectj.lang.JoinPointクラスを使用して、結合ポイントのプロパティにアクセスできます。


いい答えだ!やっと違いがわかりました!
Dante

2

mgrovesに同意します。ポイントカットは、複数のジョイントポイントの集まりと見なすことができます。ジョイントポイントは、アドバイスを実装できる特定の場所を指定します。ポイントカットにはすべてのジョイントポイントのリストが反映されます。


0

JoinPoint:これは、アドバイスが実行されるアプリケーション内のポイント(メソッド)を指定します。

ポイントカットジョインポイントの組み合わせであり、どのジョインポイントアドバイスを実行するかを指定します。


-5

参加ポイントは、実際にアドバイスを配置する場所です

ただし、ポイントカットは結合ポイントのコレクションです。つまり、クロスカットロジックを配置する方法をポイントカットと呼びます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.