2010年1月8日金曜日

[Java] Jersey リソースクラスのライフサイクル

サーブレットは1つのインスタンスがコンテナ終了まで使い回されるわけだけど、Jersey のリソースクラスのライフサイクルはどうなっているのか調べてみた。

Jersey User Guide 2.10. Life-cycle of Root Resource Classes によると、
a new instance of a root resource class is created every time the request URI path matches the root resource.

とある。リソースへのHTTPリクエストが発生するたびにインスタンスが生成されるとのこと。

@Singleton アノテーションや @PerSession アノテーション(どちらもJAX-RSではなくJersey独自のもの)を使うと、
ライフサイクルをWebアプリの起動/停止またはセッションの開始/終了にあわせることもできるそうなので、
ちょっと実験。

まず、HTTPリクエストごとに生成される、ノーマルなリソースクラス。インスタンス変数 count をもたせて、GETアクセスがくるとインクリメントする。

@Path("/normal-resource")
public class NormalResource {

private int count;

public NormalResource() {
count = 0;
}

@GET
@Produces("text/plain")
public String getCount() {
count += 1;
return "Normal Resource: " + "count = " + Integer.toString(count);
}
}


次に、セッションごとに生成されるリソースクラス。普通のリソースクラスに@PerSession アノテーションをつけるだけ。

@PerSession
@Path("/persession-resource")
public class PerSessionResource {
private int count;

public PerSessionResource() {
count = 0;
}

@GET
@Produces("text/plain")
public String getCount() {
count += 1;
return "PerSession Resource: " + "count = " + Integer.toString(count);
}
}


そして、Webアプリ内で1度だけ生成されるシングルトンリソースクラス。@Singletonアノテーションをつける。


@Singleton
@Path("/singleton-resource")
public class SingletonResource {
private int count;

public SingletonResource() {
count = 0;
}

@GET
@Produces("text/plain")
public String getCount() {
count += 1;
return "Singleton Resource: " + "count = " + Integer.toString(count);
}
}



以上3つのリソースをGlassFish v3 にデプロイしてアクセスしてみる。

/normal-resource
1回目。




2回目。


3回目。


count は何度アクセスしても 1 なのでインスタンスは確かにリクエストごとに生成されている。

/persession-resource
1回目。


2回目。


3回目。


count はアクセスごとに増えるので、インスタンスは使いまわされている。

/singleton-resource
1回目。


2回目。


3回目。


こちらも count はアクセスごとに増える。


ブラウザを立ち上げ直して新しいセッションからアクセスしてみる。

/persession-resource


count の値は 1 に戻った。つまり、新しいインスタンスが生成されている。

/singleton-resource


こちらは、count の値はリセットされない。セッションが違っても同じインスタンスが使い回されていることが確認できる。


デフォルトのリソースクラスはHTTPリクエストごとに使い捨てられるので、安心して使える。
毎回インスタンスを生成するコストについては、JVMの初期化処理やGCがとても進歩しているからパフォーマンスには影響しない、とある。
RailsのControllerも確かリクエストごとに生成してるんだっけ。

0 件のコメント:

コメントを投稿