Spring AOP AspectJアノテーションの例
このチュートリアルでは、AspectJアノテーションとSpring AOPフレームワークを統合する方法を説明します。シンプルなSpring AOP AspectJでは、メソッドを簡単にインターセプトできます。
一般的なAspectJアノテーション:
-
@ Before
– メソッドの実行前に実行する -
@ After
– メソッドが結果を返した後に実行 -
@ AfterReturning
– メソッドが結果を返した後に実行し、インターセプトします.
戻り値も同様です。
-
@ AfterThrowing
– メソッドが例外をスローした後に実行する -
@ 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.
-
Anti annotation or using JDK 1.4 ?**
No worry, AspectJ supported XML configuration also, read this
Spring
AOP + AspectJ XML example
.
Download Source Code
Download it –
Spring3-AOP-AspectJ-Example.zip
(8 KB)