SpringAOP-実装

Springは @AspectJ annotation style アプローチと schema-based カスタムアスペクトを実装するためのアプローチ。

XMLスキーマベース

アスペクトは、XMLベースの構成とともに通常のクラスを使用して実装されます。

このセクションで説明されているAOP名前空間タグを使用するには、次のように説明されているSpringAOPスキーマをインポートする必要があります。

<?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」が構成され、依存性が注入されます。

ポイントカットの宣言

A PointCutさまざまなアドバイスを使用して実行する対象のジョインポイント(つまり、メソッド)を決定するのに役立ちます。XMLスキーマベースの構成で作業している間、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.tutorialspointのStudentクラスで使用可能なgetName()メソッドの実行と一致する「businessService」という名前のPointCutを定義します。

<aop:config>
   <aop:aspect id = "myAspect" ref = "aBean">

   <aop:PointCut id = "businessService"
      expression = "execution(* com.tutorialspoint.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は、Java5アノテーションが付けられた通常のJavaクラスとしてアスペクトを宣言するスタイルを指します。@AspectJのサポートは、XMLスキーマベースの構成ファイル内に次の要素を含めることで有効になります。

<aop:aspectj-autoproxy/>

アスペクトの宣言

Aspectsクラスは、他の通常の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>

ポイントカットの宣言

A 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.tutorialspointのStudentクラスで使用可能なgetName()メソッドの実行と一致する「getname」という名前のPointCutを定義しています。

import org.aspectj.lang.annotation.PointCut;

@PointCut("execution(* com.tutorialspoint.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(){
   ...
}