サーブレット内からシングルトン Java オブジェクトにアクセスすると、そのオブジェクトは特定のサーブレット スレッドに対して「単一」または「1 つのインスタンス」にすぎないか、またはサーバー OS (Linux など) 上の JVM 全体で単一ですか?
つまり、クライアントがサーブレット/サービスに接続するとき、シングルトン オブジェクトはクライアントごとに作成された各スレッドに固有なのか、それともマシンにインストールされている JVM 全体で固有なのか?
オブジェクトは JVM 全体ではなく、ユーザーごとに一意だと思います。唯一の永続的な情報は、ユーザー セッションに入力した情報です。
よくわかりませんが、 ClassLoader クラスを使用して Application Server 全体でクラスのインスタンスを 1 つ持つことはできると思いますが、その方法はわかりません。
アップデート:
Java の記事「シングルトンがシングルトンではない場合」から引用
異なるクラス ローダーによって同時にロードされる複数のシングルトン 2 つのクラス ローダーがクラスをロードする場合、実際にはクラスの 2 つのコピーがあり、それぞれが独自のシングルトン インスタンスを持つことができます。これは、特定のサーブレット エンジン (iPlanet など) で実行されるサーブレットに特に関連します。この場合、各サーブレットはデフォルトで独自のクラス ローダーを使用します。ジョイント Singleton にアクセスする 2 つの異なるサーブレットは、実際には 2 つの異なるオブジェクトを取得します。
複数のクラス ローダーが発生するのは、思っているよりも一般的です。ブラウザがアプレットで使用するためにネットワークからクラスをロードするとき、ブラウザはサーバー アドレスごとに個別のクラス ローダーを使用します。同様に、Jini および RMI システムは、クラス ファイルのダウンロード元となるさまざまなコード ベースに対して個別のクラス ローダーを使用する場合があります。独自のシステムでカスタム クラス ローダーを使用している場合、すべて同じ問題が発生する可能性があります。
異なるクラス ローダーによってロードされた場合、同じ名前の 2 つのクラスは、同じパッケージ名であっても、別個のものとして扱われます。実際には、バイトごとに同じクラスであってもです。異なるクラス ローダーは、(クラスの名前が同じであっても) クラスを区別する異なる名前空間を表すため、2 つの MySingleton クラスは実際には区別されます。(参考文献の「名前空間メカニズムとしてのクラス・ローダー」を参照してください。) 2 つの Singleton オブジェクトが同じ名前の 2 つのクラスに属しているため、一見すると同じクラスの 2 つの Singleton オブジェクトがあるように見えます。
シングルトンの実装方法にもよると思いますが、特定のアプリに対するすべてのリクエストは同じ VM で実行されるため、すべてのリクエストに対して 1 つのインスタンスにする必要があります。
編集:これは、次のような単純なシングルトン実装を想定しています:
public class MySingleton {
private static MySingleton _instance;
// for sake of simplicity, I've left out handling of
// synchronization/multi-threading issues...
public static MySingleton getInstance() {
if (_instance == null) _instance = new MySingleton();
return _instance;
}
}
はい、そうですSingleton
。ただし、シングルトンのスコープは、クラスが配置されている場所によって異なります。
アプリケーション内にある場合は、そのアプリケーションのシングルトンです。同じクラスが別のアプリケーション内に存在する場合、そのアプリケーション用に別のオブジェクトが作成され、そのアプリケーションのシングルトンになります。
アプリケーションの外部でサーバー内にある場合は、VM のシングルトンです。
Singleton インスタンスを作成すると、すべてのリクエスト インスタンスは、現在使用しているクラス ローダーの同じインスタンスを共有します。
Servlets
単一の で実行される Web サーバー上ですべてが実行されるため、すべてのサーブレットに対してJVM
単一のSingelton
オブジェクトのみが存在します。