スポンサード リンク

S2AOP アスペクトの自動登録

ページ 目次

  1. S2AOP アスペクトの自動登録
スポンサード リンク

1.S2AOP アスペクトの自動登録

S2AOPはもとのソースに手を入れることなく、ログの出力や、例外の処理、または自分で作成したAOPをかけることができます。
便利なAOPの機能も一回一回設定ファイルを書かないといけないとなると魅力が半減してしまいます。
Seasar2にはコンポーネントの自動登録という機能がありましたが、同様にS2AOPにもアスペクトの自動登録の機能が用意されています。
今回は、S2AOPにあらかじめ用意されている「TraceInterceptor」を自動登録機能を用いてかけてみたいと思います。
作成するファイルは以下のようになります。

パッケージ名 クラス名 説明
sample.aop AopAutoMain.java サンプルのメインクラス
sample.aop AopAutoService.java サンプルクラスから使用されるインターフェース
sample.aop AopAutoServiceImpl.java サンプルクラスから使用される実装クラス
sample.aop aop_auto.dicon 設定ファイル

AopAutoMain.java

package sample.aop;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;

/**
 * AOPの自動登録のサンプルメインクラス。
 */
public class AopAutoMain {
    // 設定ファイルのPath
    private static final String PATH = "sample/aop/aop_auto.dicon";


    /**
     * @param args
     */
    public static void main(String[] args) {

        // 設定ファイルを読み込む.
        SingletonS2ContainerFactory.setConfigPath(PATH);

        // 初期化する.
        SingletonS2ContainerFactory.init();

        // コンテナを取得する.
        S2Container container = SingletonS2ContainerFactory.getContainer();

        displayComponent(container);

        AopAutoService aas = (AopAutoService) container
                .getComponent(AopAutoService.class);

        aas.aopAutoCheck(false);
    }

    /**
     * 登録しているコンポーネントとアスペクトを表示する.
     * @param container コンテナ
     */
    private static void displayComponent(S2Container container) {
        // 登録しているコンポーネントを表示する。
        for (int i = 0; i < container.getComponentDefSize(); i++) {
            String compName = container.getComponentDef(i).getComponentName();
            Class className = container.getComponentDef(i).getComponentClass();

            if (compName != null && className != null) {
                System.out.println("コンポーネント名 : " + compName + " : クラス名 : "
                        + className.toString());
                int aopSize = container.getComponentDef(i).getAspectDefSize();
                for (int j = 0; j < aopSize; j++) {
                    System.out.println(" AOP : "
                            + (j + 1)
                            + " : "
                            + container.getComponentDef(i).getAspectDef(j)
                                    .getAspect().getMethodInterceptor()
                                    .getClass().getName());
                }
            }
        }
    }
}
	

AopAutoService.java

package sample.aop;

/**
 * Aopの対象のコンポーネント
 */
public interface AopAutoService {

    /**
     * サンプルチェック.
     * @param arg 引数
     * @return 戻り値
     * */
    public void aopAutoCheck(boolean arg);

}
	

AopAutoService.java

package sample.aop;

/**
 */
public class AopAutoServiceImpl implements AopAutoService {

    /**
     * 実装クラス。
     */
    public void aopAutoCheck(boolean arg) {
        System.out.println("実装クラスの実行:" + arg);
    }

}
	

aop_auto.dicon

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN"
"http://www.seasar.org/dtd/components24.dtd">
<components>
	<!-- ログ出力用のコンポーネント -->
	<component name="traceInterceptor" class="org.seasar.framework.aop.interceptors.TraceInterceptor"/>

	<!-- コンポーネントの自動登録-->
    <component
    	class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
    	<property name="autoNaming">
    	  <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
        </property>
        <initMethod name="addClassPattern">
    	  <arg>"sample.aop"</arg>
    	  <arg>"AopAuto.*Impl"</arg>
    	</initMethod>
    </component>

    <!-- アスペクトの自動登録 -->
    <component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
        <property name="interceptor">traceInterceptor</property>
            <initMethod name="addClassPattern">
    	        <arg>"sample.aop"</arg>
    	  	    <arg>"AopAuto.*Impl"</arg>
    	    </initMethod>
	</component>
</components>

AOPの自動登録で肝となるのはやはり設定ファイルのaop_auto.diconになります。
以前行ったコンポーネントの自動登録と同じように正規表現を用いて登録することができます。
アスペクトの自動登録の部分を記載しているのは

    <!-- アスペクトの自動登録 -->
    <component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
        <property name="interceptor">traceInterceptor</property>
            <initMethod name="addClassPattern">
    	        <arg>"sample.aop"</arg>
    	        <arg>"AopAuto.*Impl"</arg>
    	    </initMethod>
	</component>
	

の部分になります。
自動登録の際に使用するコンポーネントは「org.seasar.framework.container.autoregister.AspectAutoRegister」になります。
property name="interceptor"の部分には使用するAOPのnameを記載します。
今回の場合は宣言してあるorg.seasar.framework.aop.interceptors.TraceInterceptorの名前をつけたtraceInterceptorを記載します。
次に記載されている初期化のメソッドはaddClassPatternを使用しています。
第一引数に対象のコンポーネントの保存してあるパッケージ、第二引数に対象のコンポーネントの命名規則を正規表現にて記載します。
以上でAOPをかけるための準備は完了です。
ここで注意しなければならない点はコンポーネントの登録をアスペクトの自動登録の前に行わなければならない。という点になります。
それでは実際に実行してみたいと思います。

DEBUG S2Containerを作成します。path=sample/aop/aop_auto.dicon
DEBUG S2Containerを作成しました。path=sample/aop/aop_auto.dicon
INFO  Running on [ENV]product, [DEPLOY MODE]Normal Mode
コンポーネント名 : traceInterceptor : クラス名 : class org.seasar.framework.aop.interceptors.TraceInterceptor
コンポーネント名 : aopAutoService : クラス名 : class sample.aop.AopAutoServiceImpl
 AOP : 1 : org.seasar.framework.aop.interceptors.TraceInterceptor
DEBUG BEGIN sample.aop.AopAutoServiceImpl#aopAutoCheck(false)
実装クラスの実行:false
DEBUG END sample.aop.AopAutoServiceImpl#aopAutoCheck(false) : null
	

実行結果の以下の部分に関しては、どこのコンポーネントが登録されており、かつ対象のコンポーネントにどのクラスがAOPとしてかかっているかを表示しています。

コンポーネント名 : traceInterceptor : クラス名 : class org.seasar.framework.aop.interceptors.TraceInterceptor
コンポーネント名 : aopAutoService : クラス名 : class sample.aop.AopAutoServiceImpl
AOP : 1 : org.seasar.framework.aop.interceptors.TraceInterceptor
 	

今回の自動登録のコンポーネントの対象であるaopAutoServiceに、TraceInterceptorがかけられており、実行時にログが表示されていることがわかります。



Seasar2 Topに戻る
inserted by FC2 system