建立對象生組件執行個體

來源:互聯網
上載者:User
建立|對象


    建立指令碼運行期庫對象的執行個體與建立任何其他對象和組件的執行個體化方式完全相同。可使用ASP Server對象提供的CreateObject方法(確保對象建立在當前頁面的環境內),或者使用一個<OBJECT>元素。我們將研究這兩種方法,究竟採用那種方法依賴於頁面的需要。

5.2.1 使用Server.CreateObject方法
       正如在研究Server對象的時候看到的,組件或其他對象執行個體可根據它們的ProgID來建立:
       <%
       Dim objThis
       Set objThis = Server.CreateObject(“ADODB.Connection”)
       %>
       ProgID字串“正式的”格式是“供應商.組件.版本”,供應商的名字和版本是可選的。通常ProgID只包含前兩部分(如上例)。少數供應商在ProgID中設定版本編號,這將避免向後相容的新版本使用同樣的ProgID,這要求改變ASP頁面才能使用新版本。

5.2.2 使用<OBJECT>元素
       可以使用標準的HTML<OBJECT>元素通過增加RUNAT參數並指定其值為“SERVER”來在伺服器上建立一個組件執行個體。另外,通常是提供對象的ProgID字串而不是數位ClassID:
       <OBJECT ID=”objThis” RUNAT=”SERVER” PROGID=”This.Object”>
              <PARAM NAME=”param1” VALUE=”value1”>
              <PARAM NAME=”param2” VALUE=”value2”>
       </OBJECT>
       如果上面指令碼的對象有相應的屬性可在指令碼中使用,在<OBJECT>元素內可通過<PARAM>元素進行設定,就像通常在HTML頁面中所做的一樣。在ASP中使用<OBJECT>元素時不要求CODEBASE屬性,當其不可用時,伺服器不會試圖下載以及安裝對象或組件。
1.  指定一個ClassID
另外,可以指定想要建立的對象或組件的ClassID。在不知道目標機安裝了什麼其他組件的情況下,這是非常有用的。例如在用戶端上的瀏覽器的頁面上執行個體化組件時。
在理論上,組件的ProgID(文本“供應商.組件”)不應該相互衝突,應該是唯一的。然而,這不是無懈可擊的。有可能美國北方的一個供應商與希臘小島上的一個供應商同名。但是,使用ClassID識別訪問時,因為ClassID是唯一的,同名情況就不會發生。
如果決定使用對象或組件的ClassID,應將其放入CLASSID屬性中,而不是PROGID屬性。如:
<OBJECT ID=”objThis” RUNAT=”SERVER”
              CLASSID=”clsid:892D6DA7-E0F9-11D2-B2E9-00105A42AF30”>
       <PARAM NAME=”param1” VALUE=”value1”>
       <PARAM NAME=”param2” VALUE=”value2”>
</OBJECT>
但在自己的伺服器上執行個體化對象時,應該知道對象和組件的安裝方式。這樣在ASP代碼中建立對象執行個體時,可以安全地使用ProgID。這就是ClassID很少在ASP頁面內使用的原因。然而,因為ProgID用於尋找ClassID,如果願意也可以用組件或對象的ClassID代替ProgID。
2.  設定對象執行個體的範圍
預設情況下,所有ASP頁面中建立的對象與組件執行個體(無論用Server.CreateObject方法或<OBJECT>元素)都有頁面內的範圍(page scope)。這意味著,對象與組件只有該頁在ASP上運行時才存在,當頁面完成並且把結果發送到用戶端以後就自動地取消了。
然而,如果在global.asa檔案(它存在於網站或虛擬應用程式的根目錄)中放置<OBJECT>聲明,可以將對象或組件的範圍指定為應用程式或會話範圍。
(1)    在應用程式層範圍建立對象
通過設定SCOPE屬性為“APPLICATION”,建立應用程式層範圍對象:
<OBJECT ID=”objThis” RUNAT=”SERVER” PROGID=”This.Object”
       SCOPE=”APPLICATION”>
</OBJECT>
應用程式開始時建立了對象執行個體,即一旦使用者從虛擬應用程式的目錄請求一個頁面,就建立對象執行個體。對於預設Web網站,這可以是網站上的任一目錄。直到應用程式結束(最後的使用者會話結束)前,對象執行個體一直存在,並且可以被虛擬應用程式或網站目錄內任一頁面內的任意使用者引用和使用。
(2)    在會話層範圍建立對象
如果想建立由單個使用者使用的對象執行個體,其範圍為他訪問的所有頁面,可建立會話層範圍對象。這通過將SCOPE屬性設定為“SESSION”來實現:
<OBJECT ID=”objThis” RUNAT=”SERVER” PROGID=”This.Object”
SCOPE=SESSION”>
</OBJECT>
對象一旦被引用就被建立,引用是由使用者從虛擬應用程式或網站載入的頁面內的程式碼完成的(在global.asa檔案中有<OBJECT>聲明)。當使用者會話生命週期結束並被取消時,它引用的對象執行個體也就取消了。
(3)    關於範圍和狀態
使對象執行個體的範圍為全域的或者為使用者會話全域環境看起來是一個好主意,但在實際使用時有些問題需要考慮,其中之一是在使用者的許多請求之間能夠有效地保護對象的狀態。換句話說,可以設定對象的一些屬性,它們對使用的所有頁面是共用的。因為不必每次都建立新的執行個體並設定其屬性,所以這看起來是個較好的辦法。
事實上,微軟建議一般情況下不要這樣做,這一思想是傳統程式設計思想的殘餘。在Web上,要面對的最大問題是伺服器以及Web應用程式及所提供的動態網頁如何應付數以百萬計的網站訪問者。將組件執行個體駐留在記憶體中等待一個特定使用者的頁面請求,對可能有幾百個使用者同時瀏覽的網站來說,這樣做不能有效地使用資源。
Windows 2000提供新的COM+運行期特性,它能夠處理組件的建立、緩衝和使用,採用一種輸送量最大化但所佔伺服器資源最小化的方式。對象執行個體儲存在哪裡和儲存多久的問題,最好由作業系統自己完成,而不是由程式員決定。
也就是說,在頁面內需要的地方建立對象執行個體,當頁面終止時讓其消失。COM+整理這些片段,自動處理背景一些複雜工作。如果要瞭解有關這方面的內容,第14章比較詳細地研究了組件的建立。
當然,在某種情況下,我們可能要求一個對象具有應用程式層和會話層的範圍,尤其是在頁面請求間儲存狀態時。在後面討論Dictionary對象時,將有一個這方面的執行個體。

5.2.3  Server.CreateObject與<OBJECT>的區別
       Server.CreateObject方法立即建立一個對象執行個體。在大多數情況下這也是我們所希望的。而<OBJECT>元素只有首次引用一個對象時才建立指定的對象執行個體。因此如果在代碼中停止使用該對象,則不建立該對象執行個體。
       如果代碼只在某種情況下使用這個對象(可能依賴於請求參數的值),這也許是有用的。因為如果不需要這個對象,則可以節省伺服器的資源。
       然而,如果肯定需要建立某一對象,可使用Server.CreateObject方法完成。用<OBJECT>元素建立對象有助於防止在代碼中取消對對象的調用時,忘記取消程式中的Server.CreateObject行,當然這是一個粗心的程式設計。
       最後需要記住的是,如果對象是使用Server.CreateObject方法建立的,就可以從會話或應用程式中去掉對象,但使用<OBJECT>元素建立的,則不行。

5.2.4  組件執行緒模式
       在頁面內使用對象或組件時,應該考慮的另一個問題是該對象涉及到的響應多個請求的行為方式。事實上在ASP裡,這是所需要理解的最複雜的題目之一。一個組件的執行緒模式,結合其範圍,影響該組件和應用程式的效能和效率,也影響將它執行個體化的ASP頁面。
       線程就是由處理器執行的系統對象,用於完成由組件代碼定義的任務。每一個線程都可以被認為是單個二進位指令集。在像Windows這樣的多線程環境中,多個線程可同時運行。
       實際上有五個執行緒模式(包括在Windows 2000裡引入的Neutral-threading模型):
       · Single-threaded(單線程):某一時刻只能有一個進程使用某組件。
       · Apartment-threaded(單元線程):若干進程都可以使用某組件,但只有一個在指定的線程上。
       · Neutral-threaded(中立線程):若干進程都能使用某組件,並且可以使用指定的一組線程中的任何一個。
       · Multiple-threaded或Free-threaded(多線程或自由線程):若干進程都能使用某組件,並且這些進程可以運行在不同的線程上。
       · Both-threaded(雙線程):對象既可以是單元線程的又可以作為自由線程的。
       在這裡不解釋執行緒模式的技術細節,本書後面有相應的內容。
       單元線程的組件(例如使用Visual Basic建立的或作為XML指令碼的組件)可在頁面層範圍內很好地運行,在會話層範圍內也是可以接受的。事實上,在頁面層,由於較低的資料處理開銷,也能很好地運行雙線程的組件。
       Winodws 2000中的中立線程的模型甚至提供了更好的效能,儘管到目前為止只有很少的這樣的組件和與之相適應的開發工具。
       如果需要會話層組件,使用可用的雙線程的組件。並且如果需要應用程式層範圍,可一直使用雙線程的組件。
       然而,微軟建議避免使用會話層範圍的組件,甚至不使用應用程式層範圍的組件,除非這些組件是絕對需要的。使組件的啟用時間超過範圍為頁面級的組件所要求的時間,對於由COM+提供代理特性的對象是沒有益處的。5.2.5 引用物件類型庫
    在早先的ASP版本中,在指令碼中使用對象或組件時,組件內定義的公用常數(如果有的話)在ASP裡將不再有效。這意味著我們需要自己聲明它們(或等價物)並指定相應的值。
    例如,當在早期版本的ASP中使用ActiveX資料庫物件(ADO)組件時(將在第8章進行詳細的研究),不得不用記錄集的Open方法加入預定義常數聲明。例如:
    Const adOpenKeyset = &H0001
    Const adLockPessimistic = &H0003
    Const adCmdTable = &H0002
    …
    rs.Open “Contact”,”DSN=GlobalExampleData;UID=examples;Password=;”, _
            adOpenKeyset, adLockPessimistic, adCmdTable
    …
    另一種方法是使用#include指令在頁面插入一個名為adovbs.inc的檔案。該檔案由IIS/ASP提供,包含ADO所需的所有預定義常數。更新代碼時,必須確認使用的是最新版本,並檢查它對於所有的頁面請求都可用。
    對於IIS 5.0,有一個更好的方法,通過在HTML注釋元素內使用METADATA指令,可以給組件或對象的類型庫增加引用(IIS 4.0不支援這一功能)。
    <!-- METADATA TYPE=”TypeLib”
                   FILE=”path_and_name_of_file”
                   UUID=”type_library_uuid”
                   VERSSION=”major_version_number.minor_version_number”
                   LCID=”locale_id”
    -->
    其中:
    · path_and_name_of_file是某一類型庫檔案(.tlb)或ActiveX DLL的絕對實體路徑,必須提供這一參數或者是type_library_uuid參數。
· type_library_uuid是該類型庫的唯唯一識別碼,必須提供這一參數或者是path_and_name_of_file參數。
    · major_version_number.minor_version_number(可選)定義了所需組件的版本。如果沒有該版本則使用最近的版本。
    · locale_id(可選)是地區標誌符。如果在該地區沒有發現類型庫,電腦將使用預設的(安裝時定義的)地區。
    因此,使用這一技術,通過使用下面的代碼,能使內建的ADO預定義常數在ASP頁面可用:
    <!-- METADATA TYPE=”TypeLib”
                FILE=”C:Program FilesCommon FilesSystemadomsado15.dll”
    -->
    檔案名稱msado15.dll還可用於更高版本(2.50以後)的ADO組件。
    如果ASP不能裝載類型庫,就返回一個錯誤並停止該頁的執行。可能的錯誤提示如表5-1所示:
表5-1  錯誤提示代碼及說明
錯 誤    說 明
ASP 0222    無效的類型庫說明
ASP 0223    未找到類型庫
ASP 0224    類型庫不能載入
ASP 0225    類型庫不能打包(即ASP不能從指定的類型庫中建立類型庫封裝對象)

5.2.6 在用戶端上建立對象執行個體
    在ASP中討論在伺服器上執行個體化對象和組件的技術時,值得強調的是在瀏覽器中運行用戶端頁面而完成同樣工作的方式。如果你使用ASP建立包含用戶端指令碼程式的頁面,或者使用<OBJECT>元素建立用戶端組件執行個體,將會發現這是非常有用的。在大多數情況下,指令碼運行期對象可在用戶端上執行個體化和使用,效果與伺服器上的ASP相同。
1.    VBScript CreateObject方法
在用戶端使用CreateObject時,在瀏覽器的環境內建立組件或對象執行個體,它們與瀏覽器運行在相同的記憶體空間裡(即進程內),除非實現的對象是帶有.exe擴充檔案名稱的可執行檔。
通常指定對象的ClassID,而不是使用ProgID字串,這樣就不可能與其他安裝在用戶端的對象發生衝突。
<SCRIPT LANGUAGE=”VBScript”>
Dim objThis
Set objThis = CreateObject(“clsid:892D6DA7-E0F9-00105A42AF30”)

</SCRIPT>
當然也可以使用ProgID,並且使用通用的對象或組件(特別是標準安裝提供的對象或組件),那麼得到錯誤的組件的風險是很小的:
<SCRIPT LANGUAGE=”VBScript”>
Dim objThis
Set objThis = CreateObject(“Scripting.Dictionary”)

</SCRIPT>
2.    Jscript ActiveXObject方法
為了在用戶端上執行個體化Jscript的對象和組件,必須使用ActiveXObject方法和new操作符:
<SCRIPT LANGUAGE=”JScript”>
    var objMyData = new ActiveXObject(‘clsid: 892D6DA7-E0F9-00105A42AF30’);
</SCRIPT>
或:
<SCRIPT LANGUAGE=”JScript”>
    var objMyData = new ActiveXObject(‘this.object’);
</SCRIPT>
3.    <OBJECT>元素技術
也可使用<OBJECT>元素建立用戶端對象或組件的執行個體。應省略RUNAT屬性或者將其設定為“CLIENT”。然而,這個屬性在用戶端上是被忽略的,因此設定這個屬性的唯一目的就是,在ASP頁面使用<OBJECT>元素執行個體化伺服器端的組件執行個體時防止混淆。
<OBJECT ID=”objThis” RUNAT=”CLIENT”
        CLASSID=”clsid: 892D6DA7-E0F9-00105A42AF30”
        CODEBASE=”http://yourserver.com/components/mycomponent.cab”>
    <PARAM NAME=”param1” VALUE=”value1”>
    <PARAM NAME=”param2” VALUE=”value2”>
</OBJECT>
注意,這裡出現的CODEBASE屬性,表示允許下載並安裝來自URL的組件(如果該組件沒有安裝)。IE 3.0以上的版本有此功能。
對於使用<OBJECT>元素的方法、可使用的屬性、在用戶端使用的值,可查看網站http://msdn.Microsoft.com/workshop/author/dhtml/reference/objects/OBJECT.asp,或者Windows 2000 Platform SDK文檔中的<OBJECT> tags,或者看看《IE5 Dynamic HTML Programmer’ Reference》一書,ISBN 1-861001-74-6,Wrox出版社。




相關文章

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。