Spring2.5の@AspectJアノテーションを試す

Spring2.0から使えるようになったアノテーションでのAOPを試したので忘れないように書きます。
Apressから出ている"Spring Recipes"を見ながら試しました。
自分が忘れないように残すだけなので説明しません。

ソースファイル

AnotationSampleMain.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

import beans.SampleException;
import beans.TopBean;

public class AnotationSampleMain {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ApplicationContext context = new FileSystemXmlApplicationContext("applicationContext.xml");
		TopBean topBean = (TopBean)context.getBean("topBean");
		try {
			topBean.method1();
		} catch (SampleException e) {
		}
		System.out.println(topBean.method2());
	}

}

beans.TopBean.java

package beans;

public interface TopBean {
	public void method1() throws SampleException;
	public String method2();
}

beans.TopBeanImpl.java

package beans;

public class TopBeanImpl implements TopBean {

	private SecondBean secondBean;
	
	public void setSecondBean(SecondBean secondBean) {
		this.secondBean = secondBean;
	}
	
	@Override
	public void method1() throws SampleException {
		secondBean.submethod1();

	}

	@Override
	public String method2() {
		return secondBean.submethod2();
	}

}

beans.SecondBean.java

package beans;

public interface SecondBean {
	public void submethod1() throws SampleException;
	public String submethod2();
}

beans.SecondBeanImpl.java

package beans;

public class SecondBeanImpl implements SecondBean {

	@Override
	public void submethod1() throws SampleException {
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		throw new SampleException();
		
	}

	@Override
	public String submethod2() {
		return "Susumu";
	}

}

beans.SampleException.java

package beans;

public class SampleException extends Exception {
	public SampleException() {
		super();
	}
}

Aspectのソース
aspect.SampleAspect.java

package aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;

@Aspect
public class SampleAspect {
	
	@Before("execution(* beans.TopBean.method2(..))")
	public void beforeOperation() {
		System.out.println("before called");
	}

	@After("execution(* beans.TopBean.method2(..))")
	public void afterOperation() {
		System.out.println("after called");
	}	
	
	
	@AfterReturning(pointcut="execution(* beans.TopBean.method2(..))",
			returning = "retVal")
	public void afterReturningOperation(Object retVal) {
		System.out.println("after returning returns:" + retVal.toString());
	}
	
	@Around("execution(* beans.TopBean.method2(..))")
	public Object aroundOperation(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("before around");
		Object result = joinPoint.proceed();
		System.out.println("after around");
		return result;

	}
	
	@AfterThrowing(pointcut="execution(* beans.TopBean.*(..))",
	throwing = "e")
	public void afterThrowingOperation(JoinPoint joinPoint, Throwable e) {
		System.out.println("after throwing:" + e.toString());
	}
}

設定ファイル

applicationContext.xml

<?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-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

<!-- この1行でアノテーションが使えるようになる -->
<aop:aspectj-autoproxy/>

	<bean id="topBean" class="beans.TopBeanImpl">
		<property name="secondBean" ref="secondBean"/>
	</bean>

	<bean id="secondBean" class="beans.SecondBeanImpl"/>

	<!-- これを忘れるとダメ -->
	<bean class="aspect.SampleAspect"/>
	
</beans>

実行結果

after throwing:beans.SampleException
before called
before around
after called
after returning returns:Susumu
after around
Susumu

必要なライブラリ

Springに付属してくる以下のライブラリを使った。

  1. aspectjrt.jar
  2. aspectjweaver.jar
  3. spring.jar
  4. commons-logging.jar