ASP.NET中的動(dòng)態(tài)編譯
1.為什么要進(jìn)行預(yù)編譯
ASP.NET 2.0的編譯方式大體可以分成兩種:動(dòng)態(tài)編譯和預(yù)編譯,要回答為什么要進(jìn)行預(yù)編譯,我們先要看看動(dòng)態(tài)編譯有什么不好的地方。我們回顧一下上一篇介紹的ASP.NET進(jìn)行動(dòng)態(tài)編譯的簡(jiǎn)單的流程:當(dāng)來(lái)自Brower的一個(gè)基于aspx的Http request抵達(dá)Web server,IIS handle這個(gè)request,通過(guò)分析注冊(cè)在IIS中的Application Mapping,將Request 傳給aspnet_isapi.dll ISAPI extension。ISAPI extension通過(guò)HttpRuntime進(jìn)入Http Runtime Pipeline,HttpRuntime為每個(gè)Request創(chuàng)建一個(gè)單獨(dú)的HttpContext對(duì)象,用于保存request的Context信息。在Http Runtime Pipeline中,Http request會(huì)被注冊(cè)的一系列的Http module處理,比如OutputCache Module,Session Module,Authentication Module,Authorization,ErrorHandler Module等等。在Pipeline的終端,ASP.NET需要需要根據(jù)request創(chuàng)建對(duì)應(yīng)的HttpHandler對(duì)象來(lái)處理該Request,并生成結(jié)果Response到Client。對(duì)于一個(gè)基于Aspx的Http request,對(duì)應(yīng)的Http handler對(duì)象一般就是一個(gè)System.Web.UI.Page對(duì)象。
ASP.NET會(huì)先判斷對(duì)應(yīng)的Page type是否存在于被Cache的Assembly中,如果存在,直接創(chuàng)建Page對(duì)象,否則ASP.NET會(huì)先對(duì)該P(yáng)age的相關(guān)的Source code (包括code behind,html等等) 進(jìn)行編譯,我們也說(shuō)過(guò)這種編譯是一Directory為單位的,也就是說(shuō),處于同一個(gè)Directory下的需要編譯的文件會(huì)被編譯成到同一個(gè) Assembly中。編譯生成的Assembly會(huì)被Cache,用于后續(xù)的Request。
正是因?yàn)閷?duì)資源的首次訪問(wèn)會(huì)導(dǎo)致一次編譯(這樣說(shuō)不太準(zhǔn)確,因?yàn)閯?dòng)態(tài)編譯是以directory為單位進(jìn)行的,應(yīng)該對(duì)對(duì)某個(gè)Directory下的資源進(jìn)行首次訪問(wèn)),這樣會(huì)嚴(yán)重降低Web Application的響應(yīng)速度。所以我們?yōu)榱吮苊膺@種情況,需要預(yù)先對(duì)web site進(jìn)行編譯,所以提高web site的響應(yīng)是進(jìn)行預(yù)編譯的最重要的原因。
同時(shí)動(dòng)態(tài)編譯就以為著Web server上放置的是Source code,而且他們是可被修改的。而對(duì)于一個(gè)開發(fā)完畢的Web Application,我們更希望以Binary Assembly的方式進(jìn)行部署,這樣Server上部署的都是Binary Assembly,不怕被別人篡改而導(dǎo)致系統(tǒng)的崩潰,從知識(shí)產(chǎn)權(quán)來(lái)講,也更利于保護(hù)商業(yè)秘密。這也是我們?yōu)槭裁匆M(jìn)行預(yù)編譯的另一個(gè)原因。
下面我們就來(lái)講講如何進(jìn)行預(yù)編譯,以及與編譯背后的原理。同時(shí)在這里我需要特別提出的是,在上一部分講的一些術(shù)語(yǔ)和原理,比如Preservation file,F(xiàn)astObjectFactory,同樣適用于預(yù)編譯,重復(fù)的內(nèi)容,在這里就不必再介紹了。同時(shí)我也將沿用上一部的Sample。如果想看看相關(guān)的內(nèi)容,請(qǐng)參閱[原創(chuàng)]深入剖析ASP.NET的編譯原理之一:動(dòng)態(tài)編譯(Dynamical Compilation)。
2.In Place Pre-compilation V.S. Pre-compilation for Deployment
對(duì)于預(yù)編譯,有可以分為In Place Pre-compilation和Pre-compilation for Deployment,In Place Pre-compilation很簡(jiǎn)單,實(shí)際上就是把整個(gè)Web site編譯到我們一個(gè)臨時(shí)的目錄下面,這個(gè)臨時(shí)目錄也就是我們?cè)诮榻B動(dòng)態(tài)編譯提到的那個(gè)臨時(shí)目錄。而且這個(gè)編譯的方式,包括生成的文件也和動(dòng)態(tài)編譯完全一樣,唯一不同就是編譯的時(shí)間:預(yù)先編譯,編譯的范圍:整個(gè)Web site。這種編譯就是你常用的在VS的build。這種編譯方式一般用于開發(fā)階段。
為了部署為目的的編譯是我們今天討論的重點(diǎn),下面我們就著重來(lái)討論P(yáng)re-compilation for Deployment。
注:在ASP.NET的編譯都是通過(guò)一個(gè)叫做 aspnet_compiler的工具執(zhí)行的,該工具隨ASP.NET 2.0一起發(fā)布,你完全可以利用此工具以命令行的方式的執(zhí)行編譯,并通過(guò)傳遞不同的命令行開關(guān)設(shè)置不同的編譯選項(xiàng)。該工具被置于了VS中,使你可以利用 VS進(jìn)行可視化的編譯。
3.Non-updatable Pre-compilation V.S. Updatable Pre-compilation
ASP.NET 2.0為我們提供了幾種不同方式的預(yù)編譯和部署。為了弄清楚這些預(yù)編譯和部署方式,我們先來(lái)回顧一下ASP.NET 1.x下的編譯方式。我們知道在ASP.NET 1.x時(shí)代對(duì)整個(gè)Web site進(jìn)行編譯,實(shí)際上我們只會(huì)對(duì)所有C#和VB.NET等后臺(tái)代碼進(jìn)行編譯,并生成一個(gè)單一的Assembly。而Web page的aspx是不會(huì)參與編譯的。所以當(dāng)我們?cè)L問(wèn)一個(gè)Web page的時(shí)候,ASP.NET必須對(duì)aspx進(jìn)行動(dòng)態(tài)編譯。
- <%@PageLanguage="C#"AutoEventWireup="false"
- Codebehind="Default.aspx.cs"
- Inherits="Default"%>
- publicpartialclassDefault:System.Web.UI.Page
- {
- protectedvoidPage_Load(objectsender,EventArgse)
- {
- }
- }
【編輯推薦】