Spring-MVC/ステップ・バイ・ステップ

2008/04/15からのアクセス回数 10230

Springの特徴は、なんと言ってもBean定義でAOPを使ってBeanの機能を簡単に拡張できることでしょう。

AOPは以下のような場合に有効です。

  • OOPでは対応できない複数のルートクラスに跨る共通の処理を組み入れる場合
  • ソースファイルの存在しない市販パッケージに別の機能を組み入れる場合
  • 宣言的トランザクションのように特定の処理を適応する箇所をコンフィグファイルに定義してプログラムと分離したい場合

AOPの用語の説明

AOPでは、聞き慣れない用語がたくさん出てきます。

ここでは、それらを簡潔に説明し、SpringでのAOPの特徴について説明します。

Aspect

Aspectとは、adviceとjoinpointの組み合わせを指定するモジュール単位です。

Advice

Adviceとは、pointcutによって指定されたjoinpointのどのタイミングで、どのような処理を 行うかを定義したものです。

Joinpoint

Joinpointとは、プログラムの実行時にAdviceの割り込ませることが可能なコード上の位置を示します。

Pointcut

Pointcutでは、adviceを適応するjoinpointの条件を指定します。

SpringでのAOPの特徴

pringのAOPは、プロキシーを使ってメソッドへの呼び出しを横取りするInterceptorとコンテナーのどの部分にInterceptorを適応するかを指定するAdvisorから構成されています。 従って、Springでは、fieldにはAspectを適応できません。

Spring でサポートされている adivceの種類を以下に示します。

adivceの種類インタフェース適応箇所
Beforeorg.springframework.aop.BeforeAdviceメソッドが呼び出される前
After-returingorg.springframework.aop.AfterReturningAdviceリターンの直前
After-throwingorg.springframework.aop.ThrowsAdvice例外を発行する直前
Aroundorg.aopalliance.intercept.MethodInterceptorメソッド呼び出しを横取りする
Introductionorg.springframework.aop.IntroductionInterceptorInterceptorを使って新たなInterfaceを導入する

ログ出力のAdvice

各メソッドの入り口と出口でログを出力するAOPを例にSpringのAOPについて説明します。

最初に各メソッドの呼び出し前とリターン直前にログを出力する EnterMethodLogAdvice と LeaveMethodLogAdvice を作成します。

EnterMethodLogAdvice

メソッド呼び出し前の Advice(Before Advice)は、 インタフェース MethodBeforeAdvice を実装しなくてはなりません。

EnterMethodLogAdviceは、以下のようになります。

	public void before(Method method, Object[] args, Object target)
			throws Throwable {
		System.out.print("enter " + method.getName() + " args=(");
		if (args != null) {
			for (int i = 0; i < args.length; i++) {
				if (i != 0)
					System.out.print(", ");
				System.out.print(args[i]);
			}
			System.out.println(")");
		}
	}

Bean定義は、

	<bean id="enterMethodLogAdvice" class="org.springframework.showcase.aop.EnterMethodLogAdvice"/>

とします。

LeaveMethodLogAdvice

同様に、メソッドリターン直前の Advice(After Advice)は、 インタフェース AfterReturningAdvice を実装しなくてはなりません。 LeaveMethodLogAdviceのソースを以下に示します。EnterMethodLogAdviceと同様にメソッド名とリターン値を出力します。

	public void afterReturning(Object returnValue, Method method,
			Object[] args, Object target) throws Throwable {
		System.out.println("leave " + method.getName() + " return="
				+ (returnValue != null ? returnValue : "null"));
	}

Bean定義は、

	<bean id="leaveMethodLogAdvice" class="org.springframework.showcase.aop.LeaveMethodLogAdvice"/>

とします。

Pointcut

Springでは、Pointcutを正規表現で指定するJdkRegexpMethodPointcutを提供しています。

これを使ってfindがメソッド名に付くメソッドにpointcutを 定義すると以下のようになります。

	<bean id="logPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">
		<property name="pattern" value=".*find.*"/>
	</bean>

Advisor

logEnterAdvisorとlogLeaveAdvisorは、adviceとpointcutを指定して、次のようになります。

	<bean id="logEnterAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="advice" ref="enterMethodLogAdvice"/>
		<property name="pointcut" ref="logPointcut"/>
	</bean>
	<bean id="logLeaveAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="advice" ref="leaveMethodLogAdvice"/>
		<property name="pointcut" ref="logPointcut"/>
	</bean>

DefaultAdvisorAutoProxyCreatorの定義

最後にDefaultAdvisorAutoProxyCreatorをBean定義に追加し、自動的にAdvisorのProxyが生成されるようにします。

	<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

実行

ブラウザーで実行すると、findAllメソッドの前後でenterとleaveのデバッグログが出力されます。

enter findAll args=()
leave findAll return=[org.springframework.showcase.coverc.domain.Recipe@a943af, 
org.springframework.showcase.coverc.domain.Recipe@6d50ae, 
org.springframework.showcase.coverc.domain.Recipe@cbf

コメント

この記事は、

選択肢 投票
おもしろかった 10  
そうでもない 0  
わかりずらい 2  

皆様のご意見、ご希望をお待ちしております。


(Input image string)


添付ファイル: fileapplicationContext.xml 870件 [詳細]

トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-04-05 (水) 12:53:40 (24d)
SmartDoc