かなり意味不明なタイトルですが、これが一番しっくりくるのであえてコレにしました。ちなみに、この日記内でしか通用しないローカルなネーミングです。
HttpSessionにバインドされたオブジェクトの行方
昨日、blogをブラブラしてたときにある日記を見つけました。その日記では、HttpSessionに頼りまくりな構造はちょっとキモいなぁ、とかそういう内容でした。
それで、HttpSessionにバインドされたオブジェクトがどこに保存されるかはアプリケーションサーバの実装依存―つまり、オンメモリかシリアライズされるかはわからない、とありました。
メモリを節約するためにシリアライズ、デシリアライズは十分ありえるよね、って話で、言うまでも無くパフォーマンスには必ず影響出てきます。特に、オブジェクトを大量にセッションにブラ下げると何が起こるかわかんないよ、とありました。
HttpSessionなActionForm
上記内容をふまえて今回の失敗談。
StrutsのActionFormのインスタンスのスコープはstruts-config.xmlで指定しないとセッションになってます。これ自体は・・・まぁ良しとします。
で、俺が居た某プロジェクトのActironFormにこんなものが
public class HogeForm extends ActionForm {
List areList = new ArrayList();
Map koreMap = new ArrayList();
...
}
これを最初みたとき「あーリクエストで渡されてきた値をListやMapに入れ直してんだろうな。適当なオブジェクトに変換して入れてるのかもなぁ」と予想しました。
・・・が、このActionFormの各setterでこのListやMapに触ってる様子がない。対応するインスタンス変数にフツーに値入れてるだけ。じゃあ、このListやMapは何者?と思いました。
答えは、このActionFormのインスタンスをセッションスコープとして使用している、です。ここで宣言されてるListやMapは複数ページにまたがって保存しときたい値が入ってます。HttpSession#setAttributeとかするかわりに、セッションスコープのActionFormのインスタンス変数に値保存してる、ってワケです。
ActionFormってリクエストで渡された値のActionへの引渡し役、って前提でソース読んでたので何してんだか最初はぜんぜん分かりませんでした。
それはさておき、これ、場合によってはそれなりに大きいActionFormのインスタンスがずーーーと残りつづけることになるんですよね。しかも、システム中でこういうHttpSessionなActionFormが何箇所もあるし、使い終わった後に中身消すとかしてない場所もあったり・・・。
大丈夫・・・じゃないよねぇ・・・。