Spring AOPの例–ポイントカット、アドバイザー
最後のSpring AOP advice examplesでは、クラスのメソッド全体が自動的にインターセプトされます。 しかし、ほとんどの場合、1つまたは2つのメソッドのみをインターセプトする方法が必要な場合があります。これが「ポイントカット」の目的です。 メソッド名でメソッドをインターセプトできます。 さらに、「ポイントカット」は「アドバイザー」に関連付ける必要があります。
Spring AOPには、3つの非常に専門的な用語が付属しています–Advices, Pointcut , Advisor、非公式な方法で…
-
アドバイス–メソッドの実行前または実行後に実行するアクションを示します。
-
ポイントカット–メソッド名または正規表現パターンにより、どのメソッドをインターセプトするかを示します。
-
アドバイザー–「アドバイス」と「ポイントカット」を1つのユニットにグループ化し、プロキシファクトリオブジェクトに渡します。
最後のSpring AOP advice examplesをもう一度確認します。
ファイル:CustomerService.java
package com.example.customer.services; public class CustomerService { private String name; private String url; public void setName(String name) { this.name = name; } public void setUrl(String url) { this.url = url; } public void printName(){ System.out.println("Customer name : " + this.name); } public void printURL(){ System.out.println("Customer website : " + this.url); } public void printThrowException(){ throw new IllegalArgumentException(); } }
ファイル:Spring-Customer.xml
hijackAroundMethodBeanAdvice
ファイル:HijackAroundMethod.java
package com.example.aop; import java.util.Arrays; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; public class HijackAroundMethod implements MethodInterceptor { @Override public Object invoke(MethodInvocation methodInvocation) throws Throwable { System.out.println("Method name : " + methodInvocation.getMethod().getName()); System.out.println("Method arguments : " + Arrays.toString(methodInvocation.getArguments())); System.out.println("HijackAroundMethod : Before method hijacked!"); try { Object result = methodInvocation.proceed(); System.out.println("HijackAroundMethod : Before after hijacked!"); return result; } catch (IllegalArgumentException e) { System.out.println("HijackAroundMethod : Throw exception hijacked!"); throw e; } } }
それを実行します
package com.example.common; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.example.customer.services.CustomerService; public class App { public static void main(String[] args) { ApplicationContext appContext = new ClassPathXmlApplicationContext( new String[] { "Spring-Customer.xml" }); CustomerService cust = (CustomerService) appContext .getBean("customerServiceProxy"); System.out.println("*************************"); cust.printName(); System.out.println("*************************"); cust.printURL(); System.out.println("*************************"); try { cust.printThrowException(); } catch (Exception e) { } } }
出力
************************* Method name : printName Method arguments : [] HijackAroundMethod : Before method hijacked! Customer name : Yong Mook Kim HijackAroundMethod : Before after hijacked! ************************* Method name : printURL Method arguments : [] HijackAroundMethod : Before method hijacked! Customer website : http://www.example.com HijackAroundMethod : Before after hijacked! ************************* Method name : printThrowException Method arguments : [] HijackAroundMethod : Before method hijacked! HijackAroundMethod : Throw exception hijacked!
カスタマーサービスクラスのメソッド全体がインターセプトされます。 後で、「pointcuts」を使用してprintName()
メソッドのみをインターセプトする方法を示します。
ポイントカットの例
次の2つの方法でメソッドを一致させることができます。
-
名前の一致
-
正規表現の一致
1. ポイントカット-名前一致の例
「pointcut」および「advisor」を介してprintName()メソッドをインターセプトします。 NameMatchMethodPointcutポイントカットBeanを作成し、インターセプトするメソッド名を ‘mappedName‘プロパティ値に入力します。
DefaultPointcutAdvisorアドバイザBeanを作成し、アドバイスとポイントカットの両方を関連付けます。
プロキシの「interceptorNames」を「customerAdvisor」に置き換えます(「hijackAroundMethodBeanAdvice」でした)。
customerAdvisor
完全なBean構成ファイル
customerAdvisor
もう一度実行して出力
************************* Method name : printName Method arguments : [] HijackAroundMethod : Before method hijacked! Customer name : Yong Mook Kim HijackAroundMethod : Before after hijacked! ************************* Customer website : http://www.example.com *************************
ここでは、printName()メソッドのみをインターセプトします。
PointcutAdvisor
SpringにはPointcutAdvisorクラスが付属しており、アドバイザを宣言する作業を保存し、異なるBeanにポイントカットします。NameMatchMethodPointcutAdvisorを使用して両方を1つのBeanに組み合わせることができます。
2. ポイントカット–正規表現の例
正規表現のポイントカット–RegexpMethodPointcutAdvisorを使用して、メソッドの名前を照合することもできます。
.*URL.*
これで、メソッド名に「URL」という単語が含まれるメソッドがインターセプトされます。 実際には、これを使用してDAOレイヤーを管理できます。ここで、「.*DAO. *」を宣言して、トランザクションをサポートするためにすべてのDAOクラスをインターセプトできます。