ThrowsInterceptor
使えないSpringのThrwosAdvice
のかわりに,ひがさんが素敵なThrowsInterceptor
を作ってくださいました.
SpringのThrwosAdvice
がどうして使えないのかというと,問題点が二つあるのです.
- メソッドの再実行ができない.
正確に言えばできなくはないのですが,それはjava.lang.reflect.Method
を通じて呼び出すことができるだけです.この場合,ターゲットといま例外を処理しているThrwosAdvice
との間に挟まっているAdvice(Interceptor)は実行されないはず.例えば,トランザクションAdviceがあって,その外側にデッドロックが発生した場合に限りリトライを行うAdviceを適用するなんていう場合.直接ターゲットのメソッドを実行するとトランザクションが開始されません.リトライをするには,MethodInvocation
が必要ですが,ThrwosAdvice
にはそれがない.なので使えません.
- 例外を無視できない.
例外を再スローしなくても,元の例外がスローされていきます.例外を握りつぶす手段がありません.例外ハンドリングの主たる目的はその例外を捕まえて例外的な状況から正常な状況に戻すことなのに,それができない.なので使えません.
要するにSpringのThrwosAdvice
は単なる傍観者にしかなれないわけです.これじゃあいまいち使えません.
それで嘆いていたSpringerに救世主,ひがさんのThrowsInterceptor
は両方の問題を解消してくれる素敵なしろものです.ということで,さっそく実験してみました.ネタは「AOPその8 Throws Advice」そのままです.
まずはIgnoreExceptionAdvice
をThrowsInterceptor
を継承するように修正します.
package study; import org.aopalliance.intercept.MethodInvocation; public class IgnoreExceptionAdvice extends ThrowsInterceptor { public void handleThrowable(Exception e, MethodInvocation methodInvocation) { } }
ほとんど何も変わっていません.もともと何もしていませんからね.
これ以外の定義ファイルやAdviceを適用するFoo
,実行用のMain
クラスはそのまま同じものを使って実行!!
こんな仕事やってられるか! こんな仕事やってられるか! こんな仕事やってられるか!
素晴らしい!!!
不満をもみ消して,いやな仕事をきっちり三回やらせることができました! これがやりたかったんですよ!
なおThrowsInterceptor
は,ひがさんの日記からコピペしたものにimport
文を追加した以外,まったく修正していません.何も問題なしです.
いいなぁ,これ.S2とSpringで完全に同じものが使えるといいのですが,AopConfigException
はSpringのものですよね? これをS2で使うわけにはいかないですよねぇ.こういう例外もAOP Allianceで一通り決めてくれればいいんですけどね.無念だ.
ということで,ひがさん,バッチリです!