playframework1‎ > ‎framework‎ > ‎

コントローラのstatic変数の仕組み

コントローラクラスのstatic変数で、paramsやrequestなどのオブジェクトが定義されている。
ユーザは意識せずに利用しているが、本来はスレッドごとに生成されるべきオブジェクトであり、static変数で持つべきものではない。
なぜ、playframework1では許されているのか。

実際はスレッドごとに参照されるオブジェクトが切り替わるような処理が隠ぺいされている。
発動する条件は下記に書かれている。

play.classloading.enhancers.ControllersEnhancer.isThreadedFieldAccess(CtField)
/**
 * Check if a field must be translated to a 'thread safe field'
 */
static boolean isThreadedFieldAccess(CtField field) {
    if (field.getDeclaringClass().getName().equals("play.mvc.Controller") || field.getDeclaringClass().getName().equals("play.mvc.WebSocketController")) {
        return field.getName().equals("params")
                || field.getName().equals("request")
                || field.getName().equals("response")
                || field.getName().equals("session")
                || field.getName().equals("params")
                || field.getName().equals("renderArgs")
                || field.getName().equals("routeArgs")
                || field.getName().equals("validation")
                || field.getName().equals("inbound")
                || field.getName().equals("outbound")
                || field.getName().equals("flash");
    }
    return false;
}

ここに当てはまるstatic変数はスレッドごとに参照されるが、それ以外は言語仕様通りのstatic変数として振る舞う。
調子に乗ってstatic変数を作ってスレッド変数のように扱ってはいけない。