最後の
Spring AOP adviceの例
では、クラスのメソッド全体が自動的にインターセプトされます。
しかし、ほとんどの場合、ほんの1つか2つの方法を傍受する方法が必要かもしれませんが、これが「Pointcut」の目的です。メソッド名でメソッドをインターセプトできます。さらに、 ‘Pointcut’は ‘Advisor’に関連付ける必要があります。
Spring AOPには、3つの非常に専門的な用語があります –
アドバイス、Pointcut、アドバイザー
、非公式に
実行。
-
Pointcut – メソッド名によってインターセプトするメソッドを指定する
または正規表現パターン。
-
アドバイザ – グループ「アドバイス」と「ポイントカット」を1つのユニットにまとめ、パスする
これをプロキシファクトリオブジェクトに渡します。
最後のリンク://spring/spring-aop-examples-advice/[Spring AOP adviceの例]をもう一度見直してください。
File:CustomerService.java
package com.mkyong.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();
}
}
File:Spring-Customer.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
<bean id="customerService" class="com.mkyong.customer.services.CustomerService">
<property name="name" value="Yong Mook Kim"/>
<property name="url" value="/"/>
</bean>
<bean id="hijackAroundMethodBeanAdvice" class="com.mkyong.aop.HijackAroundMethod"/>
<bean id="customerServiceProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="customerService"/>
<property name="interceptorNames">
<list>
<value>hijackAroundMethodBeanAdvice</value>
</list>
</property>
</bean>
</beans>
File:HijackAroundMethod.java
package com.mkyong.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.mkyong.common;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mkyong.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) {
}
}
}
出力
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** メソッド名:printNameメソッドの引数:[]HijackAroundMethod:メソッドがハイジャックされる前に! 顧客名:Yong Mook Kim Hijack周辺方法:ハイジャックされた後! ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Method name : printURL Method arguments :[]HijackAroundMethod : Before method hijacked! Customer website :/HijackAroundMethod : Before after hijacked! ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** メソッド名:printThrowExceptionメソッド引数:[]HijackAroundMethod:メソッドがハイジャックされる前に! HijackAroundMethod:例外をハイジャックしました!
The entire methods of customer service class are intercepted. Later, we
show you how to use “
pointcuts
” to intercept only
printName()
method.
Pointcuts example
You can match the method via following two ways :
-
Name match
-
Regular repression match
1. Pointcuts – Name match example
Intercept a printName() method via ‘pointcut’ and ‘advisor’. Create a
NameMatchMethodPointcut
pointcut bean, and put the method name you
want to intercept in the ‘
mappedName
‘ property value.
<bean id = "customerPointcut" class = "org.springframework.aop.support.NameMatchMethodPointcut"> <property name = "mappedName" value = "printName"/> </bean>
-
DefaultPointcutAdvisor ** advisor beanを作成し、両方を関連付ける
アドバイスとポイントカット。
<bean id = "customerAdvisor" class = "org.springframework.aop.support.DefaultPointcutAdvisor"> <property name = "pointcut" ref = "customerPointcut"/> <property name = "advice" ref = "hijackAroundMethodBeanAdvice"/> </bean>
プロキシの ‘interceptorNames’を ‘customerAdvisor’に置き換えてください(これは
‘hijackAroundMethodBeanAdvice’)。
<bean id = "customerServiceProxy" class = "org.springframework.aop.framework.ProxyFactoryBean"> <property name = "target" ref = "customerService"/> <property name = "interceptorNames"> <list> <value> customerAdvisor </value> </list> </property> </bean>
完全なBean構成ファイル
<beans xmlns = "http://www.springframework.org/schema/beans" xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation = "http://www .springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd "> <bean id = "customerService" class = "com.mkyong.customer.services.CustomerService"> <property name = "name" value = "Yong Mook Kim"/> <property name = "url" value = "/"/> </bean> <bean id = "hijackAroundMethodBeanAdvice" class = "com.mkyong.aop.HijackAroundMethod"/> <bean id = "customerServiceProxy" class = "org.springframework.aop.framework.ProxyFactoryBean"> <property name = "target" ref = "customerService"/> <property name = "interceptorNames"> <list> <value> customerAdvisor </value> </list> </property> </bean> <bean id = "customerPointcut" class = "org.springframework.aop.support.NameMatchMethodPointcut"> <property name = "mappedName" value = "printName"/> </bean> <bean id = "customerAdvisor" class = "org.springframework.aop.support.DefaultPointcutAdvisor"> <property name = "pointcut" ref = "customerPointcut"/> <property name = "advice" ref = "hijackAroundMethodBeanAdvice"/>/bean> </beans>
再度実行し、出力する
** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** Method name : printName Method arguments :[]HijackAroundMethod : Before method hijacked! Customer name : Yong Mook Kim HijackAroundMethod : Before after hijacked! ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** 顧客のウェブサイト:/** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** **
これで、printName()メソッドだけがインターセプトされます。
-
PointcutAdvisor
Springには
PointcutAdvisor
クラスが付属していますので、アドバイザーやポイントカットを宣言するために
Beanを使用すると、
NameMatchMethodPointcutAdvisor
を使用して単一のBeanに結合できます。
<bean id="customerAdvisor"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="mappedName" value="printName"/>
<property name="advice" ref="hijackAroundMethodBeanAdvice"/>
</bean>
2. Pointcut – 正規表現の例
また、正規表現のpointcut –
RegexpMethodPointcutAdvisor
を使用してメソッドの名前を照合することもできます。
<bean id="customerAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="patterns">
<list>
<value>.** URL.** </value>
</list>
</property>
<property name="advice" ref="hijackAroundMethodBeanAdvice"/>
</bean>
今度は、メソッド名の中に単語「URL」を持つメソッドをインターセプトします。実際には、このクラスを使用してDAOレイヤーを管理することができます。ここでは、
。
DAO。
を宣言して、すべてのDAOクラスをインターセプトしてトランザクションをサポートします。