このチュートリアルでは、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)