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クラスをインターセプトできます。