8.2 ASP.NET パイプラインとアプリケーションのライフサイクル
セクション 8.1 では、IIS のシステム アーキテクチャと HTTP 要求処理の全体的なプロセスを紹介します。そこから、各 ASP.NET Web サイトが HTTP 要求に応答してユーザーに必要な情報を提供できる Web アプリケーションに対応していることがわかります。では、ASP.NET アプリケーションは HTTP 要求にどのように正確に応答するのでしょうか?具体的にはどのような処理手順が含まれますか?これには、ASP.NET アプリケーションのライフサイクルが関係します。
8.2.1 ASP.NET アプリケーションのライフサイクル*
このセクションでは、IIS 6 を例として、ASP.NET アプリケーションによる HTTP 要求の処理プロセスを段階的に紹介します。 IIS 7 のプロセスは、IIS 6 と比較して若干の変更がいくつかありますが、一般的には一貫しています。
1 ブラウザは、ASP.NET Web ページにアクセスするための HTTP リクエストを発行します。
この要求が、この Web ページが属する ASP.NET アプリケーションに対する最初の要求であると仮定します。
この要求が Web サーバーに到達すると、HTTP.SYS はこの要求を受信し、この要求の URL に従って、この要求をこの ASP.NET アプリケーションに対応するアプリケーション プールと、このアプリケーションで実行されているアプリケーション プールに渡します。プール ワーカー プロセスはリクエストの処理を担当します[1]。
ワーカー プロセスは、この要求を受信すると、ASP.NET ページの処理専用の ISAPI 拡張機能「aspnet_isapi.dll」をロードし、それに HTTP 要求を渡します。
ワーカー プロセスが aspnet_isapi.dll をロードした後、aspnet_isapi.dll は ASP.NET アプリケーション - CLR [2] の実行環境をロードします。
ワーカー プロセスは非管理環境 (Windows オペレーティング システム自体を指します) で動作しますが、.NET のオブジェクトは管理環境 (CLR を指します) で動作し、この 2 つの環境の間で通信するブリッジとして機能します。 (非管理対象環境から) 受信した要求は、処理のために (管理対象環境内の) 対応する .NET オブジェクトに転送されます。
2 ApplicationManager オブジェクトとアプリケーション ドメインを作成します
CLR がロードされた後、ApplicationManager クラスはアプリケーション ドメインを作成します。各 ASP.NET アプリケーションは独自のアプリケーション ドメインで実行され、一意のアプリケーション ID によって識別されます。
各アプリケーション ドメインは、ApplicationManager クラスのインスタンスに対応します。このクラスは、ドメイン内で実行されている ASP.NET アプリケーションの管理 (ASP.NET アプリケーションの開始と停止、指定された ASP.NET アプリケーションでのオブジェクトの作成など) を担当します。 。
3 HostingEnvironment オブジェクトを作成する
ASP.NET アプリケーションのアプリケーション ドメインを作成すると、HostingEnvironment オブジェクトが作成され、ASP.NET アプリケーションの管理情報 (ASP.NET アプリケーションの ID、対応する仮想ディレクトリ、物理ディレクトリなど) が提供されます。また、いくつかの追加機能 (アプリケーション ドメインへのオブジェクトの登録、特定のユーザーの偽装など) を提供します。
4 要求ごとに ASP.NET Core オブジェクトを作成する
アプリケーション ドメインが作成されると、ISAPIRuntime オブジェクトが作成され、その ProcessRequest() メソッドが自動的に呼び出されます。このメソッドでは、ISAPIRuntime オブジェクトは、受信した HTTP 要求に基づいて HttpWorkerRequest オブジェクトを作成します。このオブジェクトは、HTTP 要求のさまざまな情報をオブジェクト指向の方法でラップします (つまり、元の HTTP 要求情報が HttpWorkerRequest オブジェクトとしてカプセル化されます)。次に、ISAPIRuntime オブジェクトの StartProcessing() メソッドを呼び出して、HTTP リクエスト処理プロセス全体 (これが「HTTP パイプライン: HTTP パイプライン」) を開始します。この処理プロセスの開始時に、HttpRuntime タイプのオブジェクトが作成されます。以前に作成された HttpWorkerRequest オブジェクトは、メソッド パラメータとしてこの HttpRuntime オブジェクトの ProcessRequest() メソッドに渡されます。
いくつかの非常に重要な作業は、HttpRuntime クラスの ProcessRequest() メソッドで行われます。その中で、Web ソフトウェア エンジニアに最も密接に関連する作業は次のとおりです。
HttpRuntime クラスの ProcessRequest() メソッドは、HttpWorkerRequest オブジェクトで提供された HTTP 要求情報に基づいて HttpContext オブジェクトを作成します。
HttpContext オブジェクトは、ASP.NET プログラミングで非常に一般的な他の 2 つのオブジェクト、HttpResponse と HttpRequest を含むため、重要です。
HttpRequest オブジェクト内の情報は、元の HTTP リクエストから取得されます。たとえば、その Url 属性は、元の HTTP リクエスト情報内の URL を表します。
HttpResponse オブジェクトには、ブラウザに返される情報を生成するためのいくつかのプロパティとメソッドがあります。
Page クラスは、これら 2 つのオブジェクトを参照するための対応するプロパティを提供するため、"Requset" プロパティと "Response" プロパティを直接使用して、ASP.NET Web ページ内のこれら 2 つのオブジェクトにアクセスできます。例えば:
パブリック部分クラス _Default : System.Web.UI.Page
{
protected void Page_Load(オブジェクト送信者, EventArgs e)
{
応答 .Write(リクエスト .Url);
}
}
Page クラスの Context プロパティは HttpContext オブジェクトを参照するため、上記のコードは次の形式で書き直すこともできます。
パブリック部分クラス _Default : System.Web.UI.Page
{
protected void Page_Load(オブジェクト送信者, EventArgs e)
{
this.Context.Response .Write(this.Context.Request .Url);
}
}
HttpContext、HttpResponse、および HttpRequest の 3 つのオブジェクトに関して、次の点を習得する必要があります。
l HttpContext オブジェクトには、HttpResponse と HttpRequest という 2 つのオブジェクトが含まれています。HttpRequest オブジェクトから HTTP リクエスト関連の情報を取得でき、ブラウザに出力する内容は HttpResponse メソッドを呼び出すことで実現できます。
l ASP.NET は、HTTP リクエストごとに、HTTP 処理全体を通じてアクセスできる HttpContext オブジェクトを作成します。
5 リクエストを処理するために HttpApplication オブジェクトを割り当てます。
HttpContext オブジェクトの作成に加えて、HttpRuntime クラスの ProcessRequest() メソッドは、別の非常に重要なジョブも完了します。これは、HTTP リクエスト処理全体の各ステップを管理するために、HttpApplication オブジェクトを HttpApplicationFactory クラス [3] のインスタンスに割り当てることを適用します。パイプラインの一種。
HttpApplicationFactory オブジェクトは、HttpApplication オブジェクト プール [4] を管理します。HTTP リクエストが到着すると、プール内に利用可能な HttpApplication オブジェクトがある場合、このオブジェクトは HTTP リクエストを処理するために直接割り当てられます。作成されました。
6 HttpApplication オブジェクトは HTTP パイプラインを開始します
HttpApplication オブジェクトは、「HTTP 要求処理パイプライン (HTTP パイプライン)」全体を組み立てる役割を果たします。「HTTP 要求処理パイプライン」は、現代の工場における「実稼働パイプライン」に例えることができます。前のステップで作成された HttpContext オブジェクトは、この本番パイプラインによって処理される「製品」であり、「本番パイプライン」のさまざまな部分を流れるときに、特別に処理されます。
これらの特定の「プロセスと処理」はどのように行われるのでしょうか?
簡単に言えば、HttpContext オブジェクトが「本番パイプライン」のさまざまな部分を通過すると、HttpApplication オブジェクトは一連のイベントをトリガーします [5]。特定のコンポーネント - HTTP モジュール (HTTP モジュール) はこれらのイベントに応答でき、このイベント応答コードでは、HttpContext オブジェクトを「処理および処理」できます。この意味で、HTTP モジュールは「実稼働パイプライン」とみなすことができます。 」の労働者。 HTTPモジュールの正体は先ほど紹介した「ISAPIフィルター」です。
HTTP モジュール オブジェクトは、HttpApplication オブジェクトの InitModules() メソッド [6] で作成されます。通常、HttpApplication によってトリガーされる特定のイベントに応答できるように、HTTP モジュール オブジェクトの Init() メソッド [7] にコードを記述します。物体。
ASP.NET は、特定のイベントに応答するための事前定義された HTTP モジュールをいくつか提供しており、Web ソフトウェア エンジニアは独自の HTTP モジュールを作成して、それを「HTTP 要求処理パイプライン」に挿入することもできます [8]。
パイプラインの途中 (関連イベントの処理後) で、最後の Page オブジェクトによって HttpContext オブジェクトが受信されます (これが、ASP.NET ページで Page クラスで定義された Context プロパティを介して HttpContext オブジェクトにアクセスできる理由です)。
アクセスされた各 ASP.NET ページは、「Page クラスから派生したページ クラス」に変換されます。
注: Page クラスは、ProcessRequest() メソッドを定義する IHttpHandler インターフェイスを実装します。
ASP.NET ページ クラスが生成されると、自動的にアセンブリにコンパイルされ、その ProcessRequest() メソッドが自動的に呼び出されます (Page クラスは IHttpHandler インターフェイスを実装しているため、このメソッドが必要です)。この方法では、Web ソフトウェア エンジニアが作成したコードが (存在する場合) 実行されます。 ProcessRequest() メソッドの実行結果は、HttpContext オブジェクトによって再び伝達され、制御は「HTTP 要求処理パイプライン」に戻され、HttpApplication オブジェクトは後続のイベントを起動し続けます。このとき、これらのイベントに応答する特定の HTTP モジュールがあれば、それらのモジュールが自動的に呼び出されます。
HttpContext オブジェクトは、最終的な処理結果を「HTTP リクエスト処理パイプライン」の最後まで持ってきて、その情報を取り出して、aspnet_isapi.dll をブリッジとして再びワーカープロセスに送信します。次に、ワーカー プロセスは HTTP 要求の処理結果を HTTP.SYS に転送します。HTTP.SYS は結果をブラウザーに返す役割を果たします。
前の説明によると、HTTP パイプライン全体は、前処理ステージ、処理ステージ、後処理ステージの 3 つのセクションに分割できます (図 8 ‑14)。
図 8 ‑ HTTP パイプラインの 3 つのステージ
図 8 ‑14 に示すように、HTTP パイプラインの前処理段階と後処理段階には主に複数の HTTP モジュールが参加し、これら 2 つの段階で完了する作業は主にさまざまな属性を実行することです。 HttpContext オブジェクトの改訂。
HTTP リクエストの処理は、最終的には、IHttpHandler インターフェイスを実装するオブジェクトによる「処理フェーズ」で完了します。 ASP.NET Web ページによって生成されるすべてのページ クラスは、このインターフェイスを実装します。 PageHandlerFactory オブジェクト [9] は、適切な HTTP リクエスト処理オブジェクトを作成する役割を果たします。
IHttpHandler インターフェイスを実装するオブジェクトは HTTP リクエストの処理を担当することがわかり、そのため「Handler (ハンドラー)」と呼ばれます。
最も一般的な ASP.NET Web ページに加えて、Web ソフトウェア エンジニアは、IHttpHandler インターフェイスを実装する独自のオブジェクトを作成し、それを HTTP パイプラインに挿入して HTTP 要求を処理することもできます。
HTTP リクエストが処理されると、関連するオブジェクトは解放されますが、作成されたアプリケーション ドメイン、HttpApplication、およびその他のオブジェクトは引き続き存続し、次の HTTP リクエストに応答します。
7 ASP.NET アプリケーションのライフサイクルの概要
このセクションでは、ASP.NET アプリケーションのライフ サイクルを紹介します。これは非常に複雑なプロセスです。次のようなよく知られた例えで理解すると理解しやすいでしょう。
l 「HTTP リクエスト処理パイプライン」は、現代の工場における「生産組立ライン」であり、HttpContext オブジェクトはこの組立ラインで処理される製品です。
l HttpHandler (HTTP ハンドラー) オブジェクトは、製品を形に組み立てる「製品生産ライン」全体の中核です。
l HttpModule(HTTPモジュール)は、「生産ライン」における補助作業者に相当し、製品の「前処理」(製品の組み立て準備)と「後処理」(ラベル貼り付けなどの製品出荷の準備)を行います。製品 (HttpContext オブジェクト))。
l HttpApplication オブジェクトは、「生産ライン」全体の「リーダー」であり、労働者を「生産ライン」に割り当て (登録されているすべての HttpModule を初期化してロードする)、一連のイベント (「ASP.」と呼ばれます) をトリガーする責任があります。 NET アプリケーション イベント" ")、特定の HttpModule が特定のイベントへの応答を担当します。
-------------------------------------------------- ----------------------------------
[1] ワーカー プロセスが存在しない場合は、IIS 監視プログラム WAS がワーカー プロセスを作成します。存在しない場合は、既存のワーカー プロセスが再利用されます。
[2] IIS 7 統合モードでは、CLR がプリロードされているため、この手順は必要ありません。
[3] 「クラスのインスタンス」と「クラスのオブジェクト」は同じ意味であり、どちらもクラスをテンプレートとして作成されたオブジェクトを指します。
[4] オブジェクト プール (オブジェクト プール) は、オブジェクト指向ソフトウェア システムにおける一般的なオブジェクトの編成方法であり、オブジェクトのコンテナーとみなすことができます。オブジェクト プールには、事前に作成された複数のオブジェクトが含まれます。外部がオブジェクトを必要とする場合、既製のオブジェクトをプールから直接取り出して使用できるため、頻繁なオブジェクト作成によるパフォーマンスの低下を回避できます。
[5] HttpApplication では、かなりの数のイベントが定義されています。イベントの完全なリストについては、MSDN を参照してください。
[6] このメソッドは、HttpApplication オブジェクトを取得するときに自動的に呼び出されます。
[7] すべての HTTP モジュールは IHttpModule インターフェイスを実装する必要があり、Init() メソッドはこのインターフェイスによって定義されます。
[8] カスタマイズされた HTTP モジュールは、Web.Config に特定のコンテンツを挿入することで、HTTP 要求処理フローに追加できます。
[9] これは ASP.NET テクノロジ フレームワークのもう 1 つのコアです