개요:
이 기사는 ASP.NET 2.0의 소스 코드를 기반으로 하며 ASP.NET 2.0 런타임에 대한 간략한 분석을 수행하여 ASP.NET 2.0의 요청 처리 프로세스 및 페이지 컴파일 모델을 이해하는 데 도움이 되기를 바랍니다.
키워드:
ASP.NET 2.0 런타임, 원칙, 요청 처리, 페이지 컴파일, ASP.NET 2.0 HTTP 런타임
기본 클래스:
System.Web.HttpRuntime
System.Web.HttpApplicationFactory
System.Web.HttpApplication
System.Web.Compilation.BuildManager
System.Web.Compilation.ApplicationBuildProvider
System.Web.Compilation.BuildProvidersCompiler
System.Web.UI.PageHandlerFactory
요청 처리의 간략한 흐름도:
읽기 제안:
읽는 동안 ASP.NET 2.0의 소스 코드를 보려면 Reflector 도구를 사용하십시오.
분석하다:
브라우저를 통해 ASP.NET 2.0 웹 사이트의 asp.net 페이지에 대한 요청을 시작하면 IIS가 먼저 서버 측에서 요청을 받습니다. IIS가 해당 페이지가 asp.net 페이지임을 확인하면 매우 기쁩니다. 요청을 처리할 필요가 없으며 ASP.NET ISAPI에 맡기십시오. ASP.NET ISAPI의 작업도 비교적 쉽습니다. 주요 작업은 aspnet_wp.exe가 요청을 처리하고 aspnet_wp.exe 프로세스의 실행을 모니터링하도록 하는 것입니다. 음, ASP.NET ISAPI는 그를 해고하고 새로운 aspnet_wp.exe로 교체하여 작업을 처리할 것입니다.
aspnet_wp.exe의 주요 작업은 HTTP 파이프라인이라는 일련의 관리 개체에 요청을 전달하는 것입니다. ASP.NET ISAPI를 영업 관리자에 비유하면 aspnet_wp.exe는 프로덕션 관리자이고 HTTP 파이프라인은 프로덕션 파이프라인입니다. 조립 라인을 담당하는 팀은 HttpRuntime입니다. 생산 관리자 aspnet_wp.exe는 주문(HTTP 요청)을 HttpRuntime 팀 구성원인 ProcessRequest(HttpWorkerRequest wr)에게 넘겨줍니다. HttpRuntime은 결국 ProcessRequestInternal(HttpWorkerRequest wr)에 의해 조립 라인에서 생성됩니다. ) 내부 업무 분업에 따라 분석되므로 ProcessRequestInternal(HttpWorkerRequest wr)이 분석의 초점입니다.
ProcessRequestInternal의 주요 작업은 다음과 같습니다.
1. HttpContext 인스턴스를 생성합니다.
2. 첫 번째 요청(EnsureFirstRequestInit)을 초기화합니다.
a) Web.Config 구성을 RuntimeConfig로 읽고 bin 디렉터리에서 모든 dll 파일을 로드하는 등 System.Web.HttpRuntime.FirstRequestInit를 호출하여 EnacheFirstRequestInit에서 일부 초기화 작업을 수행합니다.
3. HttpWriter 인스턴스를 생성합니다.
4. HttpApplicationFactory.GetApplicationInstance를 호출하여 HttpApplication 인스턴스를 생성합니다.
HttpApplicationFactory.GetApplicationInstance에는 세 가지 주요 메서드가 있습니다.
HttpApplicationFactory._theApplicationFactory.EnsureInited();
HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(컨텍스트);
HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(context);
이 세 가지 방법을 하나씩 분석해 보겠습니다.
1) HttpApplicationFactory._theApplicationFactory.EnsureInited();
이 메서드는 HttpApplicationFactory가 초기화되었는지 확인합니다. 그렇지 않은 경우 HttpApplicationFactory.Init()를 통해 초기화됩니다.
Init()에서 먼저 global.asax 파일의 전체 경로를 얻은 다음 CompileApplication()을 호출하여 global.asax를 컴파일하십시오.
컴파일은 어떻게 수행되나요?
컴파일 작업은 BuildManager에 의해 완료됩니다. BuildManager는 먼저 GlobalAsaxType(즉, HttpApplication)을 가져온 다음 컴파일을 위해 BuildManager.GetGlobalAsaxBuildResult() =》GetGlobalAsaxBuildResultInternal() =》EnsureTopLevelFilesCompiled()를 호출합니다.
EnacheTopLevelFilesCompiled에서는 CompilationStage.TopLevelFiles가 먼저 컴파일되고 다음 세 디렉터리의 파일이 컴파일됩니다.
a.컴파일리소스디렉토리();
App_GlobalResources 디렉터리를 컴파일합니다.
b.컴파일웹Ref디렉토리();
App_WebReferences 디렉터리를 컴파일합니다.
c.컴파일코드디렉토리();
App_Code 디렉터리를 컴파일합니다.
그런 다음 CompilationStage.GlobalAsax를 컴파일하고 global.asax를 컴파일한 다음 메서드를 호출합니다. CompileGlobalAsax()=》ApplicationBuildProvider.GetGlobalAsaxBuildResult(BuildManager.IsPrecompiledApp).
GetGlobalAsaxBuildResult의 특정 컴파일은 ApplicationBuildProvider 및 BuildProvidersCompiler에 의해 완료됩니다.
BuildProvidersCompiler.PerformBuild()는 컴파일 작업을 수행합니다.
ApplicationBuildProvider.GetBuildResult는 컴파일된 결과를 가져옵니다.
성공적으로 컴파일되면 App_global.asax.mlgx7n2v.dll과 유사한 dll 파일이 C:WINDOWSMicrosoft.NETFrameworkv2.0.50727Temporary ASP.NET Files의 해당 디렉터리에 생성됩니다.
컴파일된 클래스의 이름은 ASP.global_asax이며 HttpApplication에서 상속됩니다.
참고: 웹 디렉터리에 Global.asax 파일이 없으면 App_global.asax.mlgx7n2v.dll과 같은 파일이 컴파일 및 생성되지 않습니다.
2) HttpApplicationFactory._theApplicationFactory.EnsureAppStartCalled(컨텍스트);
특정 HttpApplication 인스턴스를 생성하고, ApplicationOnStart 이벤트를 트리거하고, ASP.global_asax에서 Application_Start(개체 전송자, EventArgs e) 메서드를 실행합니다. 여기서 생성된 HttpApplication 인스턴스는 이벤트 처리 후 재활용됩니다.
3) HttpApplicationFactory._theApplicationFactory.GetNormalApplicationInstance(컨텍스트);
이 메서드는 HttpApplication 인스턴스를 만들고 초기화합니다(System.Web.HttpApplication.InitInternal() 메서드 호출).
HttpApplication 인스턴스 생성은 실제 _theApplicationType을 기반으로 합니다. 웹 디렉터리에 global.asa 파일이 없는 경우, 즉 ASP.global_asax 유형을 생성하는 동적 컴파일이 없는 경우 HttpApplication을 직접 인스턴스화합니다. ASP.global_asax 유형이 생성되면 ASP.global_asa를 인스턴스화합니다.
HttpApplication 인스턴스를 생성한 후 인스턴스의 InitInternal 메서드를 호출합니다.
InitInternal 메서드도 우리가 중점을 두는 메서드입니다. 이 메서드의 주요 기능은 다음과 같습니다.
1. InitModules(): Web.Config의 설정에 따라 해당 HttpModules을 생성합니다.
2. HookupEventHandlersForAppplicationAndModules: 발생하는 이벤트를 기반으로 HttpApplication 인스턴스에서 해당 이벤트 처리 함수를 호출합니다.
3. IExecutionStep 인터페이스를 구현하는 클래스의 인스턴스를 여러 개 생성하고 이를 현재 HttpApplication 인스턴스의 _execSteps에 추가한 후 콜백 실행을 기다립니다. 여기에서 HttpApplication이 요청을 비동기 방식으로 처리하고 요청에 대한 많은 처리 작업이 콜백이 실행될 때까지 대기하기 위해 _execStep에 배치되는 것을 볼 수 있습니다.
_execStep의 주요 처리 작업은 다음과 같습니다.
1) 요청한 경로에 대해 보안 점검을 수행하고 불법적인 경로 접근을 금지한다(ValidatePathExecutionStep).
2) UrlMappings가 설정된 경우 RewritePath(UrlMappingsExecutionStep)를 수행합니다.
3) BeginRequest, AuthenticateRequest 등과 같은 이벤트 처리 기능을 실행합니다.
4) 현재 요청을 처리하는 HttpHandler를 가져옵니다. ASP.NET 페이지의 런타임 컴파일도 여기에서 수행됩니다. (MapHandlerExecutionStep)
이 처리는 System.Web.HttpApplication.MapHttpHandler 메서드를 호출하여 수행됩니다.
MapHttpHandler에서는 먼저 접근한 주소에 따라 web.config에서 IHttpHandlerFactory를 구현하는 해당 타입을 얻어옵니다. asp.net 페이지의 경우 기본값은 PageHanlderFactory입니다. 그런 다음 PageHanlderFactory 인스턴스를 만들고, GetHandlerHelper를 호출하고, GetHandlerHelper에서 BuildManager.CreateInstanceFromVirtualPath를 호출하여 현재 요청된 ASP.NET 페이지의 인스턴스를 컴파일하고 만듭니다(컴파일된 경우 캐시에서 직접 로드).
CreateInstanceFromVirtualPath는 여러 메서드 호출 후 CompileWebFile()에 컴파일 작업을 전달합니다. CompileWebFile은 web.config에서 해당 BuildProvider를 가져옵니다. .aspx 파일의 경우 해당 BuildProvider는 PageBuildProvider입니다. PageBuildProvider가 페이지를 컴파일하는 방법은 여기에서 더 이상 분석되지 않습니다. 관심이 있는 경우 ASP.NET 2.0의 소스 코드를 더 자세히 연구할 수 있습니다.
5) 해당 HttpHandler의 .ProcessRequest 메서드를 호출하여 요청을 처리합니다(비동기인 경우 BeginProcessReques 호출). (CallHandlerExecutionStep)
6) 응답 내용을 필터에 씁니다. (CallFilterExecutionStep)
5. HttpApplication 인스턴스의 BeginProcessRequest를 호출하여 요청을 비동기적으로 처리합니다.
위에 언급된 _execSteps에서 발생하는 많은 작업은 HttpRuntime이 HttpApplication BeginProcessRequest를 호출한 다음 BeginProcessRequest에서 ResumeSteps를 호출한 후에 실행됩니다.
ASP.NET 2.0 런타임은 매우 복잡하고 이해하기 어려우며 ASP.NET 2.0의 중요한 부분입니다. ASP.NET 2.0 런타임 소스 코드에 대한 연구는 ASP.NET 2.0의 원리를 더 깊이 이해하는 데 도움이 될 것입니다. ASP.NET 2.0 응용 프로그램을 개발하면 많은 도움이 됩니다. 이 기사는 ASP.NET 2.0 런타임을 처음 배우는 글입니다. 기사 내용에 대한 비판과 제안을 환영합니다.
글을 쓰는 것은 글쓰기 능력을 향상시키고 의사소통을 원활하게 할 수 있을 뿐만 아니라, 글을 쓰면서 자신의 생각을 명확히 하고, 깊이 있는 사고를 촉진하며, 기술에 대한 이해를 깊게 할 수 있다고 생각합니다. 개발자는 코딩에서 잠시 벗어나 시간을 보낼 수 있습니다. . 일부 기술 기사를 작성하는 것은 여전히 자신을 향상하는 데 매우 도움이 됩니다.