Apexの実行順序のことで悩んだことがあったので今回はそのことについて書きたいと思います。
Visualforceページのpageタグにaction処理が有るときと無いときでApexクラスの処理が異なる順序で実行される現象が確認されました。 検証用のソースは次の通りです。
上記のようにpageタグにactionが存在する場合は次の順序で処理が実行されます。
1. 継承クラスのコンストラクタ
2. コントローラのコンストラクタ
3. pageタグのaction処理
4. コンポーネントの継承クラス・コンストラクタ
5. コンポーネントのコンストラクタ
6. コントローラのGETメソッド
7. コンポーネントのGETメソッド
ログからも上記順序で実行されていることを確認できます。
ところがpageタグのaction処理が存在しない場合、異なる順序で実行されていました。
そのときのログがこちらになります。
ログを確認するとコントローラ側の処理より先にコンポーネント側の処理が実行されていました。
1. コンポーネントの継承クラス・コンストラクタ
2. コンポーネントのコンストラクタ
3. 継承クラスのコンストラクタ
4. コントローラのコンストラクタ
5. コントローラのGETメソッド
6. コンポーネントのGETメソッド
pageタグにactionが存在する場合は「コントローラ → コンポーネント」の順序で実行されますが、actionが存在しない場合は「コンポーネント → コントローラ」の順序で実行されるみたいです。
この順序の違いによって問題が発生することはあまりなかったと思うのですが、一つ気をつけた方が良さそうなケースがありました。
それはCookieを扱う処理を行なっている場合です。 例えばコンストラクタの処理でCookieに値をセットする処理を行います。
このときコンポーネントでそのCookieの値を使用した処理がある場合はコンストラクタより先に実行するか後に実行するかで処理結果が違ってしまいます。
コンストラクタが先に実行される場合は、常に最新のCookie情報がセットされるので問題はありません。 しかし、コンポーネントの処理が先に実行されてしまうと最新のCookie情報がセットされる前に処理が実行されるため、古いCookie情報で処理が実行されてしまいます。
このようなケースが発生してしまうためCookieの処理が必要な場合やコンポーネントの処理が先に実行されると困る場合は、pageタグのaction処理の有無に注意した方がいいみたいです。
今回の検証はAPI 27.0のバージョンで確認しています。 もしかしたら、今後のバージョンアップで統一される可能性もあるかもしれません。 個人的にはコントローラ→コンポーネントの順で実行されるように統一してもらえると嬉しいです。