-S15: ガス欠でJAFを呼ぶ
Joinpointを呼び出す(Joinpoint#proceed())前後の時期、BeforeおよびAfterと二分して説明してきたAdviceですが、Seasar2ではもうひとつAdviceの種類を実現できます。それはJoinpointにて例外が生成した場合に動作する「Exception」 Adviceです。
list15-1. 燃料が常に切れているFuelEmptyCar.java package tutorial.org.seasar.console; public class FuelEmptyCar implements Car { public void run() { throw new RuntimeException("Fuel is empty."); } }
list15-1は常にrun()メソッドでRuntimeExceptionを発生させます。
list15-2. 例外処理を行うJAF.java package tutorial.org.seasar.console; import org.seasar.framework.aop.AroundAdvice; import org.seasar.framework.aop.Joinpoint; public class JAF implements AroundAdvice { public Object invoke(Joinpoint joinpoint) throws Throwable { Object obj = null; try { obj = joinpoint.proceed(); } catch(Exception e) { System.out.println(e.getMessage()); System.out.println("No problem, there is a lot of fuel."); } return obj; } }
list15-2では、joinpoint.proceed()をtry-catchブロックで保護しています。
public Object proceed() throws Throwable;
というメソッド定義ですから例外処理の必要が無いために、これまでは例外処理をしてきませんでしたが、ここではcatchブロックに処理を記述しています。
list15-3. JAFが助けに来るcar.xml修正版 <?xml version="1.0" encoding="UTF-8"?> <components> <component class="tutorial.org.seasar.console.FuelEmptyCar"> <aspect pointcut="run"> <component class="tutorial.org.seasar.console.JAF"/> </aspect> </component> </components>
設定XMLに特別なことはありません。実行結果は、
Fuel is empty.
No problem, there is a lot of fuel.
アプリケーション内で例外処理を画一的に行いたい場合に有効な技術です。Core Concernたるコンポーネントメソッドでは例外処理は行わずに、Crosscutting ConcernであるAdviceで例外処理を行うというのは、設計的にもアリなんじゃないかと個人的には思います。このへん賛否分かれると思います。