1. ホーム
  2. java

[解決済み] サーブレットの各インスタンスとサーブレットの各スレッドの違い?重複

2023-06-11 11:38:28

質問

サーブレットクラスは複数存在するのでしょうか?私は、サーブレットの各インスタンスと聞いています。 誰かこのことについて詳しく説明できますか?

どのように解決するのですか?

サーブレットコンテナが起動するとき、それは

  1. は読みます web.xml ;
  2. はクラスパスで宣言されたServletを見つけます。
  3. 各Servletをロードし、インスタンス化する を一度だけ .

ざっくりと、こんな感じ。

String urlPattern = parseWebXmlAndRetrieveServletUrlPattern();
String servletClass = parseWebXmlAndRetrieveServletClass();
HttpServlet servlet = (HttpServlet) Class.forName(servletClass).newInstance();
servlet.init();
servlets.put(urlPattern, servlet); // Similar to a map interface.

これらのサーブレットはメモリに保存され、リクエストの URL がサーブレットに関連付けられた url-pattern . そして、サーブレットコンテナは、次のようなコードを実行します。

for (Entry<String, HttpServlet> entry : servlets.entrySet()) {
    String urlPattern = entry.getKey();
    HttpServlet servlet = entry.getValue();
    if (request.getRequestURL().matches(urlPattern)) {
        servlet.service(request, response);
        break;
    }
}

この GenericServlet#service() のいずれかを決定します。 doGet() , doPost() などをベースに呼び出すと HttpServletRequest#getMethod() .

サーブレットコンテナは 同じサーブレットインスタンス を再利用します。言い換えれば、サーブレットは すべてのリクエスト . そのため、サーブレットコードをスレッドセーフに書くことは非常に重要です。 ではなく は、リクエストやセッションのスコープ付きデータをサーブレットインスタンス変数としてではなく、メソッドのローカル変数として代入します。例えば

public class MyServlet extends HttpServlet {

    private Object thisIsNOTThreadSafe;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        Object thisIsThreadSafe;

        thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
        thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
    } 
}