2008-01-24

BlazeDS経由で呼び出されるサービスメソッドの例外ログをAOPで出力する

以前のエントリでこんなことを言った。
BlazeDSを介したメソッド呼び出しでは、メソッドが例外をスローしても BlazeDSがそれを捕まえて Flexアプリケーションに Faultオブジェクトとして(アプリケーションサーバから見れば)正常に返してしまうため、アプリケーションサーバ側では例外ログが出力されない。

アプリケーションサーバ側のログファイル(開発作業中の場合はコンソール)にスタックトレースが出力されないのではデバッグが困難なので、Springの AOPを使って例外をサーバ側でも出力させておくことにする。

必要なjarファイルを追加


Springの配布に同梱されている。
asm-2.2.3.jar
asm-commons-2.2.3.jar
asm-util-2.2.3.jar
aspectjrt.jar
aspectjweaver.jar

applicationContext.xmlにネームスペースを追加(まだ無ければ)


xmlns:aop="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"

自動weavingの設定を追加


aopネームスペースの aspectj-autoproxy要素を入れておくと、アスペクトのWeaving周りで面倒な設定をしなくても自動で色々やってくれる模様。詳しく知らないけどとにかく面倒だったものが簡単に。

<aop:aspectj-autoproxy/>

ワンポイントアドバイス:Spring 1.2の頃はこういう自動化がまだ無く、手で XMLをいっぱい書かなければならなかった。Spring AOPのことについてググる時は、ヒットした記事が Spring 1.2時代のものでないことを都度確認しないとひどい遠回りをするはめになるよ。

アスペクトの作成


例外発生時に実行される処理を担当するアスペクトを作る。こんな感じ。

package com.acme.aspect;

import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;

@Aspect // このクラスはアスペクトだよ。という印
public class ExceptionLoggingAspect {
// "com.acme.servicesパッケージ内にある全てのクラス"
// "全てのメソッド"
// "例外発生直後" を対象にこの処理が行われる
@AfterThrowing(
pointcut="execution(* com.acme.services.*.*(..))"
,throwing="ex")
public void logException(Throwable ex)
{
// 本当は commons-loggingを使うなりもっとマシな方法で
ex.printStackTrace();
}
}
こうして作ったアスペクトを applicationContext.xmlにBeanとして登録する(自動で適用されるためIDをつけて他のBeanから参照する必要は特にない)。

アスペクトの登録


<bean class="com.acme.aspect.ExceptionLoggingAspect"/>

これで FlexのRemoteObjectには Faultを返しつつサーバ側のコンソールにも例外が出力されるようになった。

ラベル:

0 件のコメント:

コメントを投稿

<< ホーム