概要
@After
, @Before
, @Finally
, @Catch
といったアノテーションを使うと、アクション処理、テンプレート処理の間に、アノテーションを付けたメソッドが実行される。
ログイン状態のチェックなど複数のアクションに対して適用したいときに便利。
適用
自クラス、@With
指定クラス、継承元クラスに記述したアノテーションが有効。
インタセプタによって機能拡張するにあたって、継承元クラスだと1つしか選択できず不便なことから@With
による指定ができるようになっている。
@With( { Extention1.class, Extention2.class } )
public class Application extends Controller {
...
インタセプタアノテーションを付与するメソッドは、public
である必要は無い。
@Before
アクション実行前に実行したいメソッドに付与する。only
で対象となるアクション名を複数指定することができる。unless
で対象外とするアクション名を複数指定することができる。
@After
アクション実行後に実行したいメソッドに付与する。@Before
と同様にonly
, unless
が指定できる。
@Finally
テンプレート処理が行われた後に実行したいメソッドに付与する。@Before
と同様にonly
, unless
が指定できる。
この時点では flash
変数やsession
変数などは辿れくなっており参照しても正しい値を返さなくなっている。例えば@Finally
でログにセッションIDを出力したいときは素直に書けないので注意。
@Catch
アクション処理で例外が発生したときに実行したいメソッドに付与する。
捕捉したい例外クラスを複数指定できる。
@Catch( { IllegalArgumentException.class, PlayException.class } )
実行順
@Before
→ action → @After
→ template → @Finally
@Catch
はactionメソッドで例外が発生すると実行される。
各アノテーションには priority
というint値を指定でき、これが小さいほど先に実行される。指定しないとゼロが指定されたものとして動作する。
ゼロが最高レベル、とコメントには書いてあるがint型なのでマイナス値を使えばさらに優先されるだろう。
実装を見ると、自クラス→@With
指定クラス→継承元、という走査を再帰的に行っているようなので、同じpriority
の場合はそれに沿った挙動になるはずだが今後も変わらない保証はない。
基本はpriority
による指定をすべき。