開発者ドキュメント

Spring AOP AspectJアノテーションの例

このチュートリアルでは、AspectJアノテーションとSpring AOPフレームワークを統合する方法を説明します。シンプルなSpring AOP AspectJでは、メソッドを簡単にインターセプトできます。

一般的なAspectJアノテーション:


  1. @ Before

    – メソッドの実行前に実行する


  2. @ After

    – メソッドが結果を返した後に実行


  3. @ AfterReturning

    – メソッドが結果を返した後に実行し、インターセプトします.

戻り値も同様です。


  1. @ AfterThrowing

    – メソッドが例外をスローした後に実行する


  2. @ Around

    – メソッド実行の周りを走り、3つのアドバイスをすべて組み合わせる

上記。

1.ディレクトリ構造

この例のディレクトリ構造を参照してください。



プロジェクトの依存関係

AspectJを有効にするには、

aspectjrt.jar



aspectjweaver.jar



spring-aop.jar

が必要です。次のMaven `pom.xml`ファイルを参照してください。

  • AspectJはSpring 2.0以降でサポートされています** この例ではSpring 3を使用していますが、AspectJの機能はSpring 2.0以降でサポートされています。


File:pom.xml

<project ...>

    <properties>
        <spring.version>3.0.5.RELEASE</spring.version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- Spring AOP + AspectJ -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.6.11</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.6.11</version>
        </dependency>

    </dependencies>
</project>

3. Spring Beans

少数のメソッドを持つ通常のBeanは、後でAspectJアノテーションを介してインターセプトします。

package com.mkyong.customer.bo;

public interface CustomerBo {

    void addCustomer();

    String addCustomerReturnValue();

    void addCustomerThrowException() throws Exception;

    void addCustomerAround(String name);
}
package com.mkyong.customer.bo.impl;

import com.mkyong.customer.bo.CustomerBo;

public class CustomerBoImpl implements CustomerBo {

    public void addCustomer(){
        System.out.println("addCustomer() is running ");
    }

    public String addCustomerReturnValue(){
        System.out.println("addCustomerReturnValue() is running ");
        return "abc";
    }

    public void addCustomerThrowException() throws Exception {
        System.out.println("addCustomerThrowException() is running ");
        throw new Exception("Generic Error");
    }

    public void addCustomerAround(String name){
        System.out.println("addCustomerAround() is running, args : " + name);
    }
}

4. AspectJを有効にする

Springの設定ファイルで、 “` <aop:aspectj-autoproxy/> `”を入れて、Aspect(インターセプタ)と通常のBeanを定義します。


File:Spring-Customer.xml

<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 ">

    <aop:aspectj-autoproxy/>

    <bean id="customerBo" class="com.mkyong.customer.bo.impl.CustomerBoImpl"/>

    <!-- Aspect -->
    <bean id="logAspect" class="com.mkyong.aspect.LoggingAspect"/>

</beans>

4. AspectJ @Before

以下の例では、 `logBefore()`メソッドは、customerBoインターフェース、 `addCustomer()`メソッドの実行前に実行されます。

  • 注意** AspectJの “pointcuts”は、どのメソッドが傍受されるかを宣言するために使用されます。このhttp://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/を参照してください。 aop.html#aop-pointcuts[Spring AOP pointcuts guide]は、サポートされているポイントカット式の完全なリストです。


File:LoggingAspect.java

package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

    @Before("execution(**  com.mkyong.customer.bo.CustomerBo.addCustomer(..))")
    public void logBefore(JoinPoint joinPoint) {

        System.out.println("logBefore() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("** ** ** ** ** ** ");
    }

}

それを実行します

    CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
    customer.addCustomer();

出力

logBefore() is running!
hijacked : addCustomer
** ** ** ** ** **

addCustomer()が実行中です。

5. AspectJ @After

以下の例では、 `logAfter()`メソッドは
customerBoインターフェース、 `addCustomer()`メソッドを実行します。


File:LoggingAspect.java

パッケージcom.mkyong.aspect;

import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.After;

@AspectパブリッククラスLoggingAspect {

@After( "execution(**  com.mkyong.customer.bo.CustomerBo.addCustomer(..))")public void logAfter(JoinPoint joinPoint){

System.out.println( "logAfter()が実行中です!"); System.out.println( "ハイジャック:" joinPoint.getSignature()。getName()); System.out.println( "** ** ** ** ** ** ");

}

}

それを実行します

CustomerBo customer =(CustomerBo)appContext.getBean( "customerBo");
    customer.addCustomer();

出力

addCustomer()はlogAfter()を実行しています!

ハイジャックされた:addCustomer
** ** ** ** ** **

6. AspectJ @AfterReturning

以下の例では、 `logAfterReturning()`メソッドは、customerBoインターフェース、 `addCustomerReturnValue()`メソッドの実行後に実行されます。さらに、 ”

returning

“属性を使用して戻り値をインターセプトできます。

戻り値をインターセプトするには、「戻る」属性(結果)の値がメソッドのパラメーター(結果)と同じである必要があります。


File:LoggingAspect.java

package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class LoggingAspect {

   @AfterReturning(
      pointcut = "execution(**  com.mkyong.customer.bo.CustomerBo.addCustomerReturnValue(..))",
      returning= "result")
   public void logAfterReturning(JoinPoint joinPoint, Object result) {

    System.out.println("logAfterReturning() is running!");
    System.out.println("hijacked : " + joinPoint.getSignature().getName());
    System.out.println("Method returned value is : " + result);
    System.out.println("** ** ** ** ** ** ");

   }

}

それを実行します

    CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
    customer.addCustomerReturnValue();

出力

addCustomerReturnValue() is running
logAfterReturning() is running!
hijacked : addCustomerReturnValue
Method returned value is : abc
** ** ** ** ** **

7. AspectJ @AfterReturning

In below example, the

logAfterThrowing()

method will be executed if
the customerBo interface,

addCustomerThrowException()

method is
throwing an exception.


File : LoggingAspect.java

パッケージcom.mkyong.aspect;

import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.AfterThrowing;

@AspectパブリッククラスLoggingAspect {

@AfterThrowing(pointcut = "実行(**  com.mkyong.customer.bo.CustomerBo.addCustomerThrowException())"、スロー= "エラー")public void logAfterThrowing(JoinPoint joinPoint、Throwable error){

System.out.println( "logAfterThrowing()が実行されています!"); System.out.println( "ハイジャック:" joinPoint.getSignature()。getName()); System.out.println( "例外:"エラー); System.out.println( "** ** ** ** ** ** ");

}
}

それを実行します

CustomerBo customer =(CustomerBo)appContext.getBean( "customerBo");
    customer.addCustomerThrowException();

出力

addCustomerThrowException()が実行中です。logAfterThrowing()が実行中です!

ハイジャックされた:addCustomerThrowException
例外:java.lang.Exception:汎用エラー
** ** ** ** ** **
スレッド "main"の例外java.lang.Exception:汎用エラー
   //...

8. AspectJ @Around

以下の例では、CustomerBoインターフェースの前に `logAround()`メソッドが実行され、 `addCustomerAround()`メソッドが呼び出され、インターセプターがいつ返すべきかを制御するために “joinPoint.proceed();”元の `addCustomerAround()`メソッドに制御します。


File:LoggingAspect.java

package com.mkyong.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;

@Aspect
public class LoggingAspect {

   @Around("execution(**  com.mkyong.customer.bo.CustomerBo.addCustomerAround(..))")
   public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {

    System.out.println("logAround() is running!");
    System.out.println("hijacked method : " + joinPoint.getSignature().getName());
    System.out.println("hijacked arguments : " + Arrays.toString(joinPoint.getArgs()));

    System.out.println("Around before is running!");
    joinPoint.proceed();//continue on the intercepted method
    System.out.println("Around after is running!");

    System.out.println("** ** ** ** ** ** ");

   }

}

それを実行します

    CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
    customer.addCustomerAround("mkyong");

出力

logAround() is running!
hijacked method : addCustomerAround
hijacked arguments :[mkyong]Around before is running!
addCustomerAround() is running, args : mkyong
Around after is running!
** ** ** ** ** **

Conclusion

It’s always recommended to apply the least power AsjectJ annotation.
It’s rather long article about AspectJ in Spring. for further
explanations and examples, please visit the reference links below.

Download Source Code

Download it –

Spring3-AOP-AspectJ-Example.zip

(8 KB)

モバイルバージョンを終了