Springaop-implementations
Spring AOP-実装
Springは、カスタムアスペクトを実装するために* @ AspectJアノテーションスタイル*アプローチと*スキーマベース*アプローチをサポートしています。
XMLスキーマベース
アスペクトは、XMLベースの構成とともに通常のクラスを使用して実装されます。
このセクションで説明されているAOP名前空間タグを使用するには、次のように説明されている春のAOPスキーマをインポートする必要があります-
<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop = "http://www.springframework.org/schema/aop"
xsi:schemaLocation = "http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<!-- bean definition & AOP specific configuration -->
</beans>
アスペクトを宣言する
*aspect* は *<aop:aspect>* 要素を使用して宣言され、バッキングBeanは次のように *ref* 属性を使用して参照されます。
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
ここでは、前の章で見たように、他のSpring Beanと同じように「aBean」が構成され、依存関係が注入されます。
PointCutの宣言
*PointCut* は、結合ポイント(つまり、 メソッド)さまざまなアドバイスを使用して実行します。 XML Schemaベースの構成で作業中、PointCutは次のように定義されます-
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:PointCut id = "businessService"
expression = "execution(* com.xyz.myapp.service.*.*(..))"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
次の例では、com.finddevguidesパッケージのStudentクラスで使用可能なgetName()メソッドの実行と一致する「businessService」という名前のPointCutを定義しています。
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:PointCut id = "businessService"
expression = "execution(* com.finddevguides.Student.getName(..))"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
アドバイスの宣言
次のように<aop:\ {ADVICE NAME}>要素を使用して、<aop:aspect>内で5つのアドバイスのいずれかを宣言できます。
<aop:config>
<aop:aspect id = "myAspect" ref = "aBean">
<aop:PointCut id = "businessService"
expression = "execution(* com.xyz.myapp.service.*.*(..))"/>
<!-- a before advice definition -->
<aop:before PointCut-ref = "businessService"
method = "doRequiredTask"/>
<!-- an after advice definition -->
<aop:after PointCut-ref = "businessService"
method = "doRequiredTask"/>
<!-- an after-returning advice definition -->
<!--The doRequiredTask method must have parameter named retVal -->
<aop:after-returning PointCut-ref = "businessService"
returning = "retVal"
method = "doRequiredTask"/>
<!-- an after-throwing advice definition -->
<!--The doRequiredTask method must have parameter named ex -->
<aop:after-throwing PointCut-ref = "businessService"
throwing = "ex"
method = "doRequiredTask"/>
<!-- an around advice definition -->
<aop:around PointCut-ref = "businessService"
method = "doRequiredTask"/>
...
</aop:aspect>
</aop:config>
<bean id = "aBean" class = "...">
...
</bean>
同じ doRequiredTask または異なるアドバイスに異なるメソッドを使用できます。 これらのメソッドは、アスペクトモジュールの一部として定義されます。
@AspectJベース
@AspectJは、アスペクトをJava 5アノテーションが付けられた通常のJavaクラスとして宣言するスタイルを指します。 @AspectJは、アスペクトをJava 5アノテーションが付けられた通常のJavaクラスとして宣言するスタイルを指します。 @AspectJサポートは、XMLスキーマベースの構成ファイル内に次の要素を含めることで有効になります。
<aop:aspectj-autoproxy/>
アスペクトを宣言する
アスペクトクラスは他の通常のBeanと同様であり、次のように@Aspectアノテーションが付けられることを除いて、他のクラスと同様にメソッドとフィールドを持つことができます。
package org.xyz;
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class AspectModule {
}
次のように、他のBeanと同様にXMLで構成されます。
<bean id = "myAspect" class = "org.xyz.AspectModule">
<!-- configure properties of aspect here as normal -->
</bean>
PointCutの宣言
*PointCut* は、結合ポイント(つまり、 メソッド)さまざまなアドバイスを使用して実行します。 @AspectJベースの構成で作業中、PointCut宣言には2つの部分があります-
- 対象のメソッド実行を正確に決定するPointCut式。
- 名前と任意の数のパラメーターで構成されるPointCut署名。 メソッドの実際の本体は無関係であり、実際には空である必要があります。
次の例では、パッケージcom.xyz.myapp.serviceの下のクラスで使用可能なすべてのメソッドの実行に一致する「businessService」という名前のPointCutを定義します。
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* com.xyz.myapp.service.*.*(..))")//expression
private void businessService() {} //signature
次の例では、パッケージcom.finddevguidesのStudentクラスで使用可能なgetName()メソッドの実行と一致する「getname」という名前のPointCutを定義しています。
import org.aspectj.lang.annotation.PointCut;
@PointCut("execution(* com.finddevguides.Student.getName(..))")
private void getname() {}
アドバイスの宣言
以下に示す@ \ {ADVICE-NAME}アノテーションを使用して、5つのアドバイスのいずれかを宣言できます。 これは、PointCut署名メソッドbusinessService()が既に定義されていることを前提としています。
@Before("businessService()")
public void doBeforeTask(){
...
}
@After("businessService()")
public void doAfterTask(){
...
}
@AfterReturning(PointCut = "businessService()", returning = "retVal")
public void doAfterReturnningTask(Object retVal){
//you can intercept retVal here.
...
}
@AfterThrowing(PointCut = "businessService()", throwing = "ex")
public void doAfterThrowingTask(Exception ex){
//you can intercept thrown exception here.
...
}
@Around("businessService()")
public void doAroundTask(){
...
}
任意のアドバイスに対してPointCutインラインを定義できます。 以下は、アドバイスの前にインラインPointCutを定義する例です。
@Before("execution(* com.xyz.myapp.service.*.*(..))")
public doBeforeTask(){
...
}