8.2 Конвейер ASP.NET и жизненный цикл приложения
В разделе 8.1 представлена системная архитектура IIS и общий процесс обработки HTTP-запросов. Из него мы можем узнать, что каждый веб-сайт ASP.NET соответствует веб-приложению, которое может отвечать на HTTP-запросы и предоставлять пользователям необходимую информацию. Итак, как именно приложение ASP.NET отвечает на HTTP-запросы? Какие конкретные процедуры обработки включены? Это касается жизненного цикла приложений ASP.NET.
8.2.1 Жизненный цикл приложения ASP.NET*
В этом разделе в качестве примера используется IIS 6, чтобы шаг за шагом представить процесс обработки HTTP-запросов приложениями ASP.NET. Процесс IIS 7 имеет некоторые незначительные изменения по сравнению с IIS 6, но в целом соответствует.
1. Браузер отправляет HTTP-запрос на доступ к веб-странице ASP.NET.
Предположим, что этот запрос является первым запросом к приложению ASP.NET, которому принадлежит эта веб-страница.
Когда этот запрос достигает веб-сервера, HTTP.SYS отвечает за его получение. Согласно URL-адресу этого запроса HTTP.SYS передает его пулу приложений, соответствующему этому приложению ASP.NET, и пулу приложений, работающему в этом приложении. Рабочие процессы пула отвечают за обработку запросов[1].
После того как рабочий процесс получает этот запрос, он загружает расширение ISAPI «aspnet_isapi.dll», предназначенное для обработки страниц ASP.NET, и передает ему HTTP-запрос.
После того как рабочий процесс загружает aspnet_isapi.dll, aspnet_isapi.dll отвечает за загрузку рабочей среды приложения ASP.NET — CLR [2].
Рабочий процесс работает в неуправляемой среде (имеется в виду сама операционная система Windows), тогда как объекты в .NET работают в управляемой среде (ссылаясь на CLR), выступая в качестве моста для связи между ними. полученные запросы (из неуправляемой среды) пересылаются соответствующему объекту .NET (в управляемой среде) для обработки.
2 Создайте объект ApplicationManager и домен приложения.
После загрузки CLR класс ApplicationManager отвечает за создание домена приложения. Каждое приложение ASP.NET выполняется в своем собственном домене приложения и идентифицируется уникальным идентификатором приложения.
Каждый домен приложения соответствует экземпляру класса ApplicationManager, который отвечает за управление приложениями ASP.NET, работающими в домене (например, запуск и остановка приложения ASP.NET, создание объектов в указанном приложении ASP.NET и т. д.). .
3. Создайте объект HostingEnvironment.
При создании домена приложения для приложения ASP.NET создается объект HostingEnvironment, который предоставляет некоторую информацию управления для приложения ASP.NET (например, идентификатор приложения ASP.NET, соответствующий виртуальный каталог и физический каталог). и предоставляет некоторые дополнительные функции (например, регистрацию объекта в домене приложения, выдачу себя за конкретного пользователя и т. д.).
4. Создайте объекты ASP.NET Core для каждого запроса.
При создании домена приложения создается объект ISAPIRuntime и автоматически вызывается его метод ProcessRequest(). В этом методе объект ISAPIRuntime создает объект HttpWorkerRequest на основе входящего HTTP-запроса. Этот объект упаковывает различную информацию HTTP-запроса объектно-ориентированным способом (то есть исходная информация HTTP-запроса инкапсулируется как объект HttpWorkerRequest). Затем вызовите метод StartProcessing() объекта ISAPIRuntime, чтобы запустить весь процесс обработки HTTP-запроса (это «HTTP-конвейер: HTTP-конвейер»). В начале этого процесса обработки создается объект типа HttpRuntime и создается объект типа HttpRuntime. ранее созданный объект HttpWorkerRequest используется как Параметры метода передаются в метод ProcessRequest() этого объекта HttpRuntime.
Некоторые очень важные работы выполняются в методе ProcessRequest() класса HttpRuntime, среди которых наиболее тесно связаны с разработчиками веб-программного обеспечения:
Метод ProcessRequest() класса HttpRuntime создает объект HttpContext на основе информации HTTP-запроса, предоставленной в объекте HttpWorkerRequest.
Объект HttpContext важен, поскольку он содержит два других объекта, которые очень распространены в программировании ASP.NET: HttpResponse и HttpRequest.
Информация в объекте HttpRequest поступает из исходного HTTP-запроса. Например, его атрибут Url представляет URL-адрес в исходной информации HTTP-запроса.
Объект HttpResponse имеет некоторые свойства и методы для генерации информации, возвращаемой браузеру.
Класс Page предоставляет соответствующие свойства для ссылки на эти два объекта, поэтому вы можете напрямую использовать свойства «Requset» и «Response» для доступа к этим двум объектам на веб-странице ASP.NET. Например:
общедоступный частичный класс _Default: System.Web.UI.Page
{
protected void Page_Load (отправитель объекта, EventArgs e)
{
Ответ.Запись(Запрос.URL);
}
}
Свойство Context класса Page ссылается на объект HttpContext, поэтому приведенный выше код также можно переписать в следующем виде:
общедоступный частичный класс _Default: System.Web.UI.Page
{
protected void Page_Load (отправитель объекта, EventArgs e)
{
this.Context.Response .Write(this.Context.Request .Url);
}
}
Что касается трех объектов HttpContext, HttpResponse и HttpRequest, вы должны освоить следующие моменты:
l Объект HttpContext содержит два объекта: HttpResponse и HttpRequest. Информацию, связанную с HTTP-запросом, можно получить из объекта HttpRequest, а содержимое, выводимое в браузер, можно получить, вызвав метод HttpResponse.
l Для каждого HTTP-запроса ASP.NET создает объект HttpContext, доступный в течение всей обработки HTTP.
5. Выделите объект HttpApplication для обработки запроса.
Помимо создания объекта HttpContext, метод ProcessRequest() класса HttpRuntime также выполняет еще одну очень важную работу — применение выделения объекта HttpApplication к экземпляру класса HttpApplicationFactory [3] для управления каждым шагом всей обработки HTTP-запроса. трубопровод. вид мероприятия.
Объект HttpApplicationFactory отвечает за управление пулом объектов HttpApplication [4]. При поступлении HTTP-запроса, если в пуле есть доступный объект HttpApplication, этот объект напрямую выделяется для обработки HTTP-запроса. В противном случае создается новый объект HttpApplication. созданный.
6. Объект HttpApplication запускает HTTP-конвейер.
Объект HttpApplication отвечает за сборку всего «конвейера обработки HTTP-запросов (HTTP Pipeline)». «Конвейер обработки HTTP-запросов» можно сравнить с «производственным конвейером» на современном заводе. Объект HttpContext, созданный на предыдущем шаге, является «продуктом», который будет обрабатываться этим производственным конвейером. Когда он проходит через разные части «производственного конвейера», он будет обрабатываться и обрабатываться особым образом.
Как происходят эти конкретные «процессы и методы лечения»?
Проще говоря, когда объект HttpContext проходит через разные части «производственного конвейера», объект HttpApplication инициирует серию событий [5]. На эти события может реагировать конкретный компонент — модуль HTTP (HTTP Module). В этом коде ответа на событие объект HttpContext может быть «обработан и обработан». В этом смысле HTTP-модуль можно рассматривать как «производственный конвейер». » рабочие в. Модуль HTTP на самом деле представляет собой представленный ранее «фильтр ISAPI».
Объект модуля HTTP создается в методе InitModules() [6] объекта HttpApplication. Обычно мы пишем код в методе Init() [7] объекта модуля HTTP, чтобы он мог реагировать на определенные события, инициируемые HttpApplication. объект.
ASP.NET предоставляет некоторые предопределенные HTTP-модули для реагирования на определенные события, а инженеры веб-программного обеспечения также могут писать свои собственные HTTP-модули и вставлять их в «конвейер обработки HTTP-запросов» [8].
В середине конвейера (после обработки связанных событий) объект HttpContext принимается конечным объектом Page (именно поэтому доступ к объекту HttpContext можно получить на странице ASP.NET через свойство Context, определенное классом Page).
Каждая страница ASP.NET, к которой осуществляется доступ, будет преобразована в «класс страницы, производный от класса Page».
Примечание. Класс Page реализует интерфейс IHttpHandler, который определяет метод ProcessRequest().
После создания класса страницы ASP.NET он автоматически компилируется в сборку, а затем автоматически вызывается его метод ProcessRequest() (поскольку класс Page реализует интерфейс IHttpHandler, он должен иметь этот метод). В этом методе выполняется код, написанный веб-разработчиком программного обеспечения (если таковой имеется). Результат выполнения метода ProcessRequest() снова передается объектом HttpContext, управление передается обратно в «конвейер обработки HTTP-запросов», а объект HttpApplication продолжает генерировать последующие события. В это время, если существуют определенные HTTP-модули, реагирующие на эти события, они будут вызываться автоматически.
Объект HttpContext переносит окончательный результат обработки в конец «конвейера обработки HTTP-запросов», а его информация извлекается и снова передается рабочему процессу с использованием aspnet_isapi.dll в качестве моста. Затем рабочий процесс передает результаты обработки HTTP-запроса в HTTP.SYS, который отвечает за возврат результатов в браузер.
Согласно предыдущему введению, весь HTTP-конвейер можно разделить на три части: этап предварительной обработки, этап обработки и этап постобработки (рис. 8 ‑14).
Рисунок 8 ‑ Три этапа HTTP-конвейера.
Как показано на рисунке 8‑14, этапы предварительной и постобработки конвейера HTTP в основном выполняются несколькими модулями HTTP и управляются событиями. Работа, выполняемая на этих двух этапах, в основном предназначена для выполнения различных атрибутов. объекта HttpContext.
Обработка HTTP-запросов в конечном итоге завершается на «фазе обработки» объектом, реализующим интерфейс IHttpHandler. Каждый класс страницы, созданный веб-страницами ASP.NET, реализует этот интерфейс. Объект PageHandlerFactory [9] отвечает за создание подходящего объекта обработки HTTP-запроса.
Видно, что за обработку HTTP-запросов отвечает объект, реализующий интерфейс IHttpHandler, поэтому он и называется «Handler (обработчик)».
Помимо наиболее распространенных веб-страниц ASP.NET, инженеры веб-программного обеспечения также могут создавать свои собственные объекты, реализующие интерфейс IHttpHandler, и вставлять их в конвейер HTTP для обработки HTTP-запросов.
При обработке HTTP-запроса связанные объекты освобождаются, но созданный домен приложения, HttpApplication и другие объекты по-прежнему сохраняются, чтобы ответить на следующий HTTP-запрос.
7. Сводка жизненного цикла приложения ASP.NET
В этом разделе описывается жизненный цикл приложений ASP.NET. Это довольно сложный процесс. Его проще понять с помощью следующей популярной аналогии.
l «Конвейер обработки HTTP-запросов» — это «производственная сборочная линия» на современном заводе, а объект HttpContext — это продукт, который будет обрабатываться на этой сборочной линии.
l Объект HttpHandler (HTTP-обработчик) — это ядро всей «линии производства продукта», отвечающее за сборку продукта в форму.
l HttpModule (HTTP-модуль) эквивалентен вспомогательным работникам на «производственной линии». Они выполняют «предварительную обработку» (подготовку к сборке продукта) и «постобработку» (подготовку к доставке продукта, например, маркировку). продукт (объект HttpContext)).
l Объект HttpApplication является «лидером» всей «производственной линии». Он отвечает за распределение работников по «производственной линии» (инициализацию и загрузку всех зарегистрированных HttpModules), а затем запуск серии событий (называемых «ASP. NET-приложений" "), конкретный HttpModule отвечает за реагирование на определенные события.
-------------------------------------------------- ----------------------------------
[1] Если рабочий процесс не существует, программа мониторинга IIS WAS создаст его, в противном случае существующий рабочий процесс будет использоваться повторно.
[2] В интегрированном режиме IIS 7, поскольку среда CLR предварительно загружена, этот шаг не требуется.
[3] «Экземпляр класса» и «объект класса» имеют одно и то же значение, и оба они относятся к объектам, созданным с использованием классов в качестве шаблонов.
[4] Пул объектов (пул объектов) — распространенный метод организации объектов в объектно-ориентированных программных системах. Его можно рассматривать как контейнер объектов. Пул объектов содержит несколько объектов, созданных заранее. Когда внешнему миру нужен объект, он может напрямую извлечь готовый объект из пула и использовать его, избегая таким образом потери производительности, вызванной частым созданием объекта.
[5] HttpApplication определяет довольно много событий. Полный список событий можно найти в MSDN.
[6] Этот метод будет автоматически вызываться при получении объекта HttpApplication.
[7] Все HTTP-модули должны реализовывать интерфейс IHttpModule, и метод Init() определяется этим интерфейсом.
[8] Настраиваемые HTTP-модули можно добавить в поток обработки HTTP-запросов, вставив определенный контент в Web.Config.
[9] Это еще одно ядро технологической среды ASP.NET.