Seasar2 S2AOPについて
独自のインターセプターの作成
ページ 目次
- 独自のインターセプターの作成
1.独自のインターセプターの作成
ログの出力、例外をキャッチするためのインターセプターと2つのあらかじめS2AOPに用意されているインターセプターを見てきました。
あらかじめ用意されているインターセプタも大変便利なのですが、自分で必要な機能を作成してかけたいということもあります。
今回は独自にインターセプターを作成し、動かしてみたいと思います。
作成するインターセプターは、traceInterceptorのように開始と終了時にログを表示するもので、
終了時に処理時間を表示されるもんのを作成したいと思います。
作成するクラスは以下のようになります。
パッケージ名 | クラス名 | 説明 |
---|---|---|
sample.aop | AopOriginalMain.java | サンプルのメインクラス |
sample.aop | AopOriginalSample.java | 独自に作成するインターセプター |
sample.aop | AopOriginalService.java | サンプルクラスから使用されるインターフェース |
sample.aop | AopOriginalServiceImpl.java | サンプルクラスから使用される実装クラス |
sample.aop | aop_orijinal.dicon | 設定ファイル |
AopOriginalMain.java
package sample.aop; import org.seasar.framework.container.S2Container; import org.seasar.framework.container.factory.SingletonS2ContainerFactory; /** * AopをかけたServiceクラスを呼び出すMainクラス。 * */ public class AopOriginalMain { // 設定ファイルのPath private static final String PATH = "sample/aop/aop_orijinal.dicon"; /** * メインクラス。 * @param args */ public static void main(String[] args) { // 設定ファイルを読み込む. SingletonS2ContainerFactory.setConfigPath(PATH); // 初期化する. SingletonS2ContainerFactory.init(); // コンテナを取得する. S2Container container = SingletonS2ContainerFactory.getContainer(); // 対象のコンポーネントを取得する AopOriginalService aos = (AopOriginalService) container .getComponent(AopOriginalService.class); // サービスの実行 try { // 10秒待つ処理をしません aos.aopOrginalCheck(false); // 10秒待つ処理をします. aos.aopOrginalCheck(true); } catch (Exception e) { e.printStackTrace(); } // 使用したコンポーネントを廃棄する. container.destroy(); } }
AopOriginalSample.java
package sample.aop; import java.text.SimpleDateFormat; import java.util.Date; import org.aopalliance.intercept.MethodInvocation; import org.seasar.framework.aop.interceptors.AbstractInterceptor; /** * 対象のコンポーネントにAOPとしてかける例外処理クラス. */ public class AopOriginalSample extends AbstractInterceptor { /** * 処理の開始と終了時にログを出力、終了時に処理時間を計測するインターセプター * * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation) */ public Object invoke(MethodInvocation invocation) throws Throwable { // 対象のクラス String actonName = getTargetClass(invocation).getName(); // 対象のメソッド String methodName = invocation.getMethod().getName(); // メソッドの引数 Object[] obList = invocation.getArguments(); StringBuilder argSb = new StringBuilder(); if (obList != null && obList.length > 0) { for (int i = 0; i < obList.length; i++) { if (i > 0) { argSb.append(","); } argSb.append(obList[i]); } } // スタートログを追加 SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); Date startDate = new Date(); long startLong = System.currentTimeMillis(); System.out.println("start : " + sdf.format(startDate) + " : " + actonName + "#" + methodName + "(" + argSb + ")"); try { // 実際の処理を実行 invocation.proceed(); } finally { // 終了ログを追加 Date endDate = new Date(); long endLong = System.currentTimeMillis(); System.out.println("end : " + sdf.format(endDate) + " : " + actonName + "#" + methodName + "(" + argSb + ")" + " 処理時間 : " + (endLong - startLong) / 1000 + " 秒"); } return null; } }
AopOriginalService.java
package sample.aop; /** * Aopの対象のコンポーネント */ public interface AopOriginalService { /** * サンプルチェック. * @param arg 引数 * @return 戻り値 * @throws Exception 例外 * */ public void aopOrginalCheck(boolean arg) throws Exception; }
AopOriginalServiceImpl.java
package sample.aop; /** * Aopの対象のコンポーネント */ public class AopOriginalServiceImpl implements AopOriginalService { /** * 処理対象のメソッドチェック. * * @param arg 引数 * @throws Exception 例外 */ public void aopOrginalCheck(boolean arg) throws Exception { System.out.println("処理を実行しますー"); if (arg) { System.out.println("引数がtrueのとき10秒処理を待ちます"); Thread.sleep(10000); } System.out.println("処理が終わりました"); } }
aop_orijinal.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 name="aopOriginalSample" class="sample.aop.AopOriginalSample"/> <!-- AOPログのコンポーネントの登録 --> <component name="AopOriginalService" class="sample.aop.AopOriginalServiceImpl"> <aspect>aopOriginalSample</aspect> </component> </components>
では実際に実行してみたいと思います。
DEBUG S2Containerを作成します。path=sample/aop/aop_orijinal.dicon DEBUG S2Containerを作成しました。path=sample/aop/aop_orijinal.dicon INFO Running on [ENV]product, [DEPLOY MODE]Normal Mode start : 2008/04/26 09:25:37 : sample.aop.AopOriginalServiceImpl#aopOrginalCheck(false) 処理を実行しますー 処理が終わりました end : 2008/04/26 09:25:37 : sample.aop.AopOriginalServiceImpl#aopOrginalCheck(false) 処理時間 : 0 秒 start : 2008/04/26 09:25:37 : sample.aop.AopOriginalServiceImpl#aopOrginalCheck(true) 処理を実行しますー 引数がtrueのとき10秒処理を待ちます 処理が終わりました end : 2008/04/26 09:25:47 : sample.aop.AopOriginalServiceImpl#aopOrginalCheck(true) 処理時間 : 10 秒
作成したインターセプターが処理されていました。
肝となるクラスは、独自に作成するインターセプタのクラスであるAopOriginalSample.javaです。
では中身を見てみたいと思います。
public class AopOriginalSample extends AbstractInterceptor {
にてorg.seasar.framework.aop.interceptors.AbstractInterceptorを継承しています。
AbstractInterceptorは、MethodInterceptorをimplementsしているので、
public Object invoke(MethodInvocation invocation) throws Throwable を実装する必要があります。
このinvokeが独自のインターセプターの処理を行います。
引数として取得しているMethodInvocationより「対象のクラス名」「対象のメソッド名」「対象のメソッドの引数」が取得できます。
今回作成したサンプルではログを表示させるところにて使用しています。
invocation.proceed();
とすることで対象のメソッドを実行させることができるので、前後で時間を計測しておくことで
実際の処理の時間を取得し、表示させています。
あとは通常のAOPをかけるときと同じように設定ファイルに記載することで独自に作成したインターセプターが適用されます。
Seasar2 Topに戻る