Search on the blog

2013年2月12日火曜日

Learn Spring Framework (4)

 昨日のAOPをアノテーションで書いてみました。
最近は、xml→アノテーションってのが主流なんですかね。Tomcatも7.0からアノテーションによるサーブレット、フィルター、リスナーの定義ができるようになってますし。

それではサンプルを説明していきます。
まず、xmlファイルです。ここにはAOPの定義は書かずに、aop:aspectj-autoproxyというタグを記述しておきます。
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:context="http://www.springframework.org/schema/context"
       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/context
        http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">

    <aop:aspectj-autoproxy />
    <context:component-scan base-package="main.java.component" />
    <context:component-scan base-package="main.java.aop" />
</beans>
次に、アドバイスクラス。まず@ComponentでBean定義します。そして、@Aspectを付与することでこのクラスをアドバイスクラスとして使うことをSpringに教えてあげます。メソッドに@After、@Before、@Aroundを付与することで、それぞれAfter Advice、Before Advice、Around Adviceとして動作させることができます。
@Afterの中の"PointCutDefine.allComponentDir()"ですが、これはポイントカットが定義されているメソッドを指します。ちょっとややこしいですが、ポイントカットそのものではなく、ポイントカットが定義されているメソッドを指します。
package main.java.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class AdviceExample {
    /*
     * before advice
     */
    @Before("PointCutDefine.allComponentDir()")
    public void before() {
        System.out.println("AdviceExample#before()");
    }
    
    /*
     * after advice
     */
    @After("PointCutDefine.allComponentDir()")
    public void after() {
        System.out.println("AdviceExample#after()");
    }
    
    /*
     * around advice
     */
    @Around("PointCutDefine.allComponentDir()")
    public Object around(ProceedingJoinPoint method) throws Throwable {
        Object ret = null;
        System.out.println("AdviceExample#around() -- begin");
        ret = method.proceed();
        System.out.println("AdviceExample#around() -- end");        
        return ret;
    }
}
最後に、ポイントカットを定義しているクラスです。ポイントカットの定義は各アドバイスの中で個別に定義することもできますが、ポイントカット定義のためのクラスを作成し共通で使用されるポイントカットを一ヶ所にまとめておくとスッキリすると思います。
package main.java.aop;

import org.aspectj.lang.annotation.Pointcut;

public class PointCutDefine {

    @Pointcut("execution(* main.java.component.*.*(..))")
    public void allComponentDir() {}
    
    @Pointcut("execution(* main.java.service.*.*(..))")
    public void allServiceDir() {}

    @Pointcut("execution(* main.java.controller.*.*(..))")
    public void allControllerDir() {}
    
}
あくまでも個人的な意見ですが、アノテーション使った方が美しいですね。

0 件のコメント:

コメントを投稿