
2007年6月14日
改寫(xiě)了一下Java基類(lèi),添加了一個(gè)計(jì)數(shù)器。
用tomcat測(cè)試了一下連續(xù)若干次請(qǐng)求時(shí)創(chuàng)建的對(duì)象個(gè)數(shù)。
第【148259】個(gè)對(duì)象
天哪,服務(wù)器啟動(dòng)開(kāi)始就是14萬(wàn)個(gè)對(duì)象。
第【148668】個(gè)對(duì)象
第【149091】個(gè)對(duì)象
第【149211】個(gè)對(duì)象
第【149291】個(gè)對(duì)象
第【149418】個(gè)對(duì)象
第【149541】個(gè)對(duì)象
第【149867】個(gè)對(duì)象
第【149947】個(gè)對(duì)象
回想一下以前人們?yōu)槌舐膕truts1的單例Action的設(shè)計(jì)的辯護(hù),真是可笑之極,哈哈哈哈
無(wú)意間看到的一片趣文:
希望有一天能看到文言文版的國(guó)外圖書(shū)翻譯,真的比較有趣,還有,不懂的時(shí)候,也可以順帶看看英文原文,也好順便學(xué)學(xué)英語(yǔ),呵呵。
引:
Thus spake the master programmer:
"When you have learned to snatch the error code from the trap frame, it will be time for you to leave."
師曰:『惑中取錯(cuò)之日,可出山矣。』
…..
全文見(jiàn):
http://livecn.huasing.org/tao_of_programming.htm
我一直都想搞一個(gè)
XML的模板引擎,大凡非xml的模板風(fēng)格,第一感覺(jué)就是那么的不爽。
可是CommonTemplate例外。
CommonTemplate處處為程序員考慮周到的漂亮的語(yǔ)法風(fēng)格,確實(shí)非常誘人。
具體的語(yǔ)法我就不一一列舉了,大家可以到他的
官方網(wǎng)站去翻閱。
挑幾個(gè)亮點(diǎn)介紹一下:
-
for循環(huán)的空處理,相信曾經(jīng)麻煩了不少程序員吧。
現(xiàn)在好了,CT支持如下語(yǔ)法:
$for{
}
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
$forelse
<tr>
<td colspan="3">沒(méi)有數(shù)據(jù)</td>
</tr>
$end
-
大膽的關(guān)鍵字利用。
<html>
<body>
$if{users != null && users.size > 0}
<table border="1">
$for{user : users}
<tr>
<td>${for.index + 1}</td>
<td>${user.name}</td>
<td>${user.coins}</td>
</tr>
$end
</table>
$end
</body>
</html>
大家看這段代碼。一般來(lái)說(shuō),for這種常用關(guān)鍵字是不好用作id的,但是這里作為默認(rèn)的循環(huán)狀態(tài)對(duì)象的id。既解決了塊對(duì)象存放的問(wèn)題,又不會(huì)引起其他命名的沖突。一個(gè)字,妙!!!!
-
其他漂亮的特征:
注釋版語(yǔ)法外套,方便于測(cè)試數(shù)據(jù)填充及可視化編輯。
單一的語(yǔ)法規(guī)則,方便解析與擴(kuò)展。
等等。。。。
好了,贊嘆之余還是給出一點(diǎn)點(diǎn)遺憾:
boolean 運(yùn)算有點(diǎn)丑陋。
我個(gè)人更期望 js的boolean運(yùn)算風(fēng)格,沒(méi)有必要一碰到boolean 運(yùn)算就返回true ? false
我們完全可以返回一個(gè)更有意義的值,比如,我更期望這個(gè)語(yǔ)句能如我所愿的執(zhí)行。
${ variable|| "默認(rèn)值"}
當(dāng)能,如上支持,CT是有的,它的寫(xiě)法是
${ variable | "默認(rèn)值"}
但是,我感覺(jué),這個(gè)語(yǔ)法就有點(diǎn)復(fù)雜了,也不那么直觀。
一般來(lái)說(shuō)| 是按位取或,是位運(yùn)算符,這里這個(gè)用法,跳躍的確實(shí)有點(diǎn)大,較難接受的。
剛剛經(jīng)歷的一點(diǎn)小技巧,共享一下。
1。給代理函數(shù)加上空判斷
一個(gè)組合模式的運(yùn)用。代碼如下:
class Composite impliments IF1,IF2,IF3{
private IF1 if1;
private IF2 if2;
private IF2 if2;
public Composite (if1,if2,if3){
}
}
eclipse 生成指代方法>>>>
class Composite impliments IF1,IF2,IF3{
private IF1 if1;
private IF2 if2;
private IF2 if2;
public Composite (if1,if2,if3){
}
public void method1(){
if1.method1();
}


.
}
//正則表達(dá)式
// (\w+method\d)(\..*) if($1!=null){$0}
//>>>
class Composite impliments IF1,IF2,IF3{
private IF1 if1;
private IF2 if2;
private IF2 if2;
public Composite (if1,if2,if3){
}
public void method1(){
if(if1= null){
if1.method1();
}
}


.
}
//還有一個(gè)構(gòu)造函數(shù)里的屬性賦值:
// (\w+) this.$1=$1
結(jié)果,略
觸類(lèi)旁通,更多新的用法待你去發(fā)掘^_^
被一個(gè)貌似hsqldb bug的問(wèn)題折磨了好幾個(gè)小時(shí)。
把經(jīng)過(guò)帖出來(lái),大家?guī)臀铱纯础?br />
習(xí)慣把hql都寫(xiě)成預(yù)定義的形式,同時(shí)又為了避免過(guò)多的hql定義,我的慣用伎倆:通過(guò)如下方式定義hql。
from Message
where packageKey=:packageKey
and ( null = :fileKey or fileKey = :fileKey)
and ( null = :objectKey or objectKey= :objectKey)
and ( null = :memberKeys or memberKey in ( :memberKeys))
但是。今天在hqldb上測(cè)試時(shí)發(fā)現(xiàn),在任何情況下 (null = ?) 都為真!!!
非常奇怪,害我調(diào)試了老半天,后來(lái)把數(shù)據(jù)庫(kù)換成了mysql,ok!!
非常奇怪啊。
不過(guò),上面的寫(xiě)法(
null = :fileKey)也有點(diǎn)怪怪的。
摘要: 剛剛學(xué)習(xí)了一下網(wǎng)頁(yè)動(dòng)畫(huà)中上的緩動(dòng)效果,分享一下學(xué)習(xí)心得。
緩動(dòng)曲線的概念:
緩動(dòng)曲線是一個(gè)0為起點(diǎn)的連續(xù)函數(shù)曲線,x軸表示時(shí)間變化,y軸表示位移變化。曲線的斜率反映出運(yùn)動(dòng)的數(shù)度。
緩動(dòng)效果在Flash動(dòng)畫(huà)中比較常見(jiàn),用于模擬一些現(xiàn)實(shí)中常見(jiàn)的運(yùn)動(dòng)軌跡,或者制造一些超絢的效果。
而且新版本的Flash中,內(nèi)置了一些常用的緩動(dòng)曲線函數(shù)。
可惜,Flash的這些曲線函數(shù)不是開(kāi)源的...
閱讀全文
目前為止,JSA依然是最強(qiáng)大的腳本壓縮工具。
As i know,JSA is the most powerfull compressor for javascript.
for jquery1.2.1 (80,469 byte;)
Compressor |
beforegzip |
aftergzip |
source: |
80,469; |
24,975; |
jquery default: |
46,437; |
14,641; |
yuicomressor |
46,210; |
14,452; |
JSA(without eval) |
40,704; |
13,604; |
JSA(with eval):
|
26,157;
|
13,549; |
JSA(webstart):
http://www.xidea.org/webstart/JSA.jnlp
JSA這個(gè)壓縮工具,是java編寫(xiě)的,需要安裝java運(yùn)行環(huán)境。
這多少給一些非jav程序員帶來(lái)點(diǎn)不便。
現(xiàn)在我們發(fā)布servlet在線壓縮版本。無(wú)需安裝,在線壓縮,給非Java用戶(hù)一個(gè)更加便捷的使用方式。
項(xiàng)目主頁(yè):http://www.xidea.org/project/jsa/
現(xiàn)在的在線壓縮服務(wù)器由Seaprince提供。
歡迎更多有空閑服務(wù)器資源的朋友安裝JSA在線服務(wù),我將在jsa項(xiàng)目主頁(yè)提供鏈接,方便大家使用。
仍外,為了避免服務(wù)器資源被惡意濫用,我們默認(rèn)啟用了圖片驗(yàn)證,服務(wù)頻率限制等保護(hù)設(shè)置。
給用戶(hù)帶來(lái)些不便,敬請(qǐng)諒解。
今天無(wú)意間打開(kāi)了一個(gè)CSDN上的個(gè)人blog,發(fā)現(xiàn)窗口無(wú)法拖動(dòng),F(xiàn)irefox的標(biāo)簽頁(yè)也無(wú)法切換。
查看代碼:
<script type="text/javascript">Include("Csdn.Blog.UserOnline");</script>
<script type="text/javascript">Include("Csdn.Blog.ShowmeDataDeal");</script>
看到Include函數(shù),馬上可以想到,它很可能使用了動(dòng)態(tài)包含腳本的設(shè)計(jì)。
//http://blog.csdn.net/scripts/jsframework.js
window.Include=function(namespace, path)
{
..
};
S.load=function(namespace, path)
{

}
仔細(xì)閱讀這兩個(gè)函數(shù)代碼,發(fā)現(xiàn)它是通過(guò)XMLHttpRequest對(duì)象同步裝載腳本資源的(對(duì)IE,它采用userdata緩存優(yōu)化)。而這必將導(dǎo)致一種完全阻塞問(wèn)題(這種問(wèn)題我在仍外一篇blog上描述過(guò):http://jindw.javaeye.com/blog/66702)。
說(shuō)到阻塞問(wèn)題,我想大家可能會(huì)以為只是一種下載延遲,其實(shí)不然。
下載延遲不是完全阻塞,瀏覽器依然可以響應(yīng)用戶(hù)事件。而同步XHR請(qǐng)求阻塞是一種完全的阻塞。
瀏覽器在腳本運(yùn)行與事件響應(yīng)共用同一個(gè)線程(我的猜測(cè))。任何腳本尚在運(yùn)行時(shí)(包括被同步XHR請(qǐng)求阻塞的時(shí)間),瀏覽器將無(wú)法響應(yīng)任何用戶(hù)事件(無(wú)法拖放窗口、切換標(biāo)簽、重畫(huà)頁(yè)面等等,就像程序死了一樣)。與普通的下載延遲造成的阻塞,感覺(jué)明顯不同。
我對(duì)這個(gè)問(wèn)題可以說(shuō)深有體會(huì),起初,在構(gòu)建JSI1的項(xiàng)目站點(diǎn)時(shí)。因?yàn)榫W(wǎng)站放在sourceforge上,訪問(wèn)數(shù)度不是一般的慢,幾個(gè)簡(jiǎn)單的例子,瀏覽器就要完全阻塞好幾妙鐘。正是厭惡這種完全阻塞的現(xiàn)象,我才開(kāi)發(fā)了JSI2。
事實(shí)上,現(xiàn)在的一堆堆js框架中,采用XHR同步裝載資源的有不少,JSVM、dojo、a9engine、hax的pies;其中JSVM,
dojo都提供打包工具,將可能裝載的腳本打包到啟動(dòng)文件中,所以也可以避免XHR同步請(qǐng)求。不過(guò)這樣也就失去了部分動(dòng)態(tài)裝載的意義了。
總之,我非常討厭這種完全阻塞現(xiàn)象,認(rèn)為這個(gè)嚴(yán)重影響用戶(hù)體驗(yàn)。
可能也有些主觀因素把,希望聽(tīng)聽(tīng)大家的看法。
最近看見(jiàn)一個(gè)JavaEye上關(guān)于Java基本類(lèi)型編譯優(yōu)化的帖子。
貌似高深莫測(cè),其實(shí)疑點(diǎn)重重。吧內(nèi)容轉(zhuǎn)貼過(guò)來(lái),希望在這里找到更合理的解釋。
這些描述我也看過(guò),很是不解。
如果說(shuō)這種基本類(lèi)型也需要用這種指針的風(fēng)格,還要共享數(shù)據(jù),那么后續(xù)的操作處理起來(lái)不是更麻煩嗎?
每次寫(xiě)操作都要查找已有常量。甚至開(kāi)辟新的空間存儲(chǔ)新值。
再說(shuō)這個(gè)指針怎么的也要個(gè)32位吧。為什么就不能直接吧值放進(jìn)去,硬是要通過(guò)指針跳來(lái)跳去的,有意義嗎?
這優(yōu)化了嗎?
反正在我看來(lái),這是不可能的。
希望有高手出來(lái)澄清一下,給個(gè)合理的解釋。
如果是對(duì)的,那也應(yīng)該給出有點(diǎn)說(shuō)服力的證據(jù)。
如果是錯(cuò)的,那么建議大家吧這篇文章的源頭揪出來(lái),這個(gè)確實(shí)誤人不淺。
不過(guò)java對(duì) String 這類(lèi)不可變對(duì)象的處理,編譯器確實(shí)有類(lèi)似優(yōu)化,不過(guò)也只是編譯期。
這種系統(tǒng)類(lèi)庫(kù)受到點(diǎn)編譯器的特別關(guān)注倒是很合理的。
* 類(lèi)庫(kù)導(dǎo)出支持(完全脫離JSI環(huán)境)
從JSI托管類(lèi)庫(kù)中,選擇文件/對(duì)象集,導(dǎo)出為單一腳本文件,完全脫離JSI裝載環(huán)境。
也就是說(shuō),屆時(shí)JSI不僅可以作為一個(gè)運(yùn)行時(shí)的腳本管理框架,也可以當(dāng)作一個(gè)部署時(shí)的腳本定制、打包工具。
我是看Ext的定制工具后產(chǎn)生這個(gè)想法的,JSI的依賴(lài)定義API完全可以用作一個(gè)通用的腳本定制、打包工具的依賴(lài)描述語(yǔ)言。
* Ext集成(歡迎Ext用戶(hù)加入)
集成Ext,一方面可以彌補(bǔ)JSI組件的缺乏。另一方面可以?xún)?yōu)化Ext的裝載延遲。
ext目前大小為:462,031字節(jié),JSI2Alpha版的內(nèi)核為35,140字節(jié),不到Ext的十分之一(文件大小均在文本壓縮之前記數(shù))。集成Ext后,用戶(hù)可以使用JSI導(dǎo)入函數(shù),按需導(dǎo)入那些頁(yè)面上直接使用到的元素。
一些細(xì)節(jié)的想法:
初步?jīng)Q定使用jquery為其基礎(chǔ)類(lèi)庫(kù)(prototype不必?fù)?dān)心,JSI可以隔離腳本沖突,不會(huì)影響到prototype用戶(hù))。
裝載單元?jiǎng)澐值膬煞N想法:
1.按照 http://extjs.com/download/build 中描述的定制模塊劃分(可能做些文件合并,避免零碎 件的裝載開(kāi)銷(xiāo))
2.按照Ext內(nèi)部包劃分(Ext 下載包的packages目錄下好像已經(jīng)做了文件合并)
我個(gè)人還沒(méi)用過(guò)Ext,非常希望有Ext用戶(hù)合作。
大約兩年前私下編寫(xiě)一個(gè)wiki時(shí)使用的代碼生成工具,最近想繼續(xù)這個(gè)wiki項(xiàng)目(http://sourceforge.net/projects/txdoc),也順便吧這個(gè)代碼生成工具整理出來(lái)。
PPT見(jiàn):http://www.tkk7.com/jindw/archive/2007/06/30/127195.html
eclipse項(xiàng)目,文件太大,SF文件發(fā)布系統(tǒng)最近問(wèn)題多多,只好分成三分上傳在javaeye blog:http://jindw.javaeye.com/blog/98436
其中,代碼生成工具及一些基礎(chǔ)類(lèi)庫(kù)在web/WEB-INF/lib/xdoclet-xidea-plus.jar文件中(附源碼)
目錄結(jié)構(gòu)
src/main: 源文件
src/gen: 生成的源文件及配置文件
src/test: 測(cè)試類(lèi)
build: ant 腳本(build.xml)、ant配置、構(gòu)建過(guò)程的臨時(shí)目錄(temp)
web: web根目錄
lib: 編譯器附加類(lèi)庫(kù)(如ant任務(wù)需要的lib)
doc: 文檔目錄
doc/xdoclet: xdoclet參考文檔
一.創(chuàng)建持久類(lèi):
1.改類(lèi)為一個(gè)有諾干屬性的簡(jiǎn)單java類(lèi)
2.為持久類(lèi)打上hibernate標(biāo)記:
必要標(biāo)記:hibernate.class(指定該類(lèi)為持久類(lèi),無(wú)必選屬性,可選屬性參考xdoclet文檔)
hibernate.id (指定持久類(lèi)主鍵,必選屬性generator-class,指定主鍵生成算法,常用算法有uuid.hex、hilo、assigned....)
常用標(biāo)記:hibernate.property(指定持久屬性,無(wú)必選屬性)
hibernate.cache(預(yù)定義查詢(xún),必選屬性 name,query)
hibernate.one-to-many,hibernate.many-to-one等,指定對(duì)象關(guān)系,比較復(fù)雜,建議先看hibernate官方文檔、xdoclet文檔
3.打開(kāi)項(xiàng)目下build/build.xml、運(yùn)行hibernate任務(wù),該任務(wù)將生成hibernate映射文件、hibernate dao實(shí)現(xiàn)、hibernate的spring配置,及dao配置。
其中hibernateDao實(shí)現(xiàn)常用DAO方法,并定義以后將使用的常量:如預(yù)定義查詢(xún)名、預(yù)定義查詢(xún)參數(shù)名、集合名,等等。
4.持久類(lèi)的路徑一般為:src/main/{package}/po/{TableName}.java ,生成的DAO路徑為src/main/{package}/dao/{TableName}Dao.java
二.創(chuàng)建Spring服務(wù)實(shí)現(xiàn):
1.Spring服務(wù)實(shí)現(xiàn)無(wú)任何接口約束,普通java對(duì)象即可。
2.將需要使用的hibernate Dao 聲明為該服務(wù)類(lèi)的屬性(spring.property標(biāo)記)。
3.為服務(wù)類(lèi)打上spring標(biāo)記:
必要標(biāo)記:spring.bean(parent:對(duì)于所有需要spring事務(wù)支持的javabean,必須聲明parent屬性值為"transactionProxy";
生成工具將根據(jù)類(lèi)名為spring bean自動(dòng)生成默認(rèn) id,)
常用標(biāo)記:spring.property(spring 屬性)。
spring.transaction(對(duì)于parent=transactionProxy的bean,需要為需要聲明是事務(wù)支持的方法聲明事務(wù)屬性,具體請(qǐng)參考xdoclet文檔)
4.打開(kāi)項(xiàng)目下build/build.xml、運(yùn)行spring任務(wù),該任務(wù)將生成spring配置文件。
三.創(chuàng)建XWork Action,一般為*/action/*.java
1.Action需要實(shí)現(xiàn)com.opensymphony.xwork.Action,如果我們需要xwork的國(guó)際化支持,繼承ActionSupport基類(lèi),必然需要實(shí)現(xiàn)TextProvider接口。
2.為Action打上x(chóng)work標(biāo)記:
必要標(biāo)記:xwork.package(必要屬性有name),
xwork.action(必要屬性name,表示某方法為Action方法,將映射到一個(gè)具體的url地址),
xwork.result(必要屬性name,該標(biāo)記定義在定義了xwork.action的地方,可定義多個(gè),表示該Action的結(jié)果集)
常用屬性: xwork.spring-ref (屬性的set方法上,其值將從spring context中獲取)
3.為Action制作結(jié)果集頁(yè)面:
若未在 xwork.result標(biāo)記中定義value屬性,其值未ActionName+"-"+resultName,若有大寫(xiě)字符,將用"-"隔開(kāi),并轉(zhuǎn)小寫(xiě);
value值即未頁(yè)面地址。可以為jsp,velocity,xsl等等。
4.打開(kāi)項(xiàng)目下build/build.xml、運(yùn)行xwork任務(wù),該任務(wù)將生成xwork配置文件。
帶ID的函數(shù)表達(dá)式:
var fn = function fnid(){};
按照ECMA262定義,上面這段腳本等價(jià)于:
with({fnid:null}){
var fn = fnid = function(){};
}
注意:fnid在with外是不可見(jiàn)的,但是IE沒(méi)有嚴(yán)格遵守ECMA規(guī)范(同樣的情況發(fā)生在catch語(yǔ)法上)。在IE上相當(dāng)于:
var fnid = function(){};
var fn = fnid;
在剛剛發(fā)布的JSA1beta上,還不能處理這個(gè)問(wèn)題(新版本將這周內(nèi)發(fā)布)。同時(shí),鑒于這種語(yǔ)法在不同瀏覽器上表現(xiàn)不同,還是建議盡量避免使用(這點(diǎn)上,我個(gè)人還是更喜歡ie的方式)。
var語(yǔ)句:
太常用了,但是,沒(méi)有注意還是很容易出問(wèn)題。
var 用來(lái)聲明全局或函數(shù)變量,但是,只是申明,重復(fù)申明也不能置空,范圍是函數(shù)或者全局空間,位置在函數(shù)或腳本頂端,與塊無(wú)關(guān),這些與常用高級(jí)語(yǔ)言區(qū)別很大。
怪癖的代碼
var vaiable =0;
function test(){
variable =1;//別擔(dān)心,不會(huì)改動(dòng)全局變量vaiable
//do 
..
var vaiable;//變量申明無(wú)順序(一律置頂),只是賦值有順序。
}
常見(jiàn)錯(cuò)誤有:
var flag;//這里可能有人(包括我自己)喜歡自做聰明的利用一下變量的初始值undefined
while(!flag){//沒(méi)準(zhǔn)那個(gè)角落里面已經(jīng)給當(dāng)前函數(shù)內(nèi)同名變量給賦值了就慘了
//
..
}
已經(jīng)有一年多沒(méi)做java這塊了,今天翻出這個(gè)一年前寫(xiě)的代碼生成工具,準(zhǔn)備開(kāi)放出來(lái),或許對(duì)某些人還有點(diǎn)用處。
這個(gè)代碼生成器是基于xdoclet2的改進(jìn)版。
所做工作:
* 生成Hibernate 映射文件及相應(yīng)得spring的配置文件。
* 生成Hibernate DAO 文件及命名查詢(xún)名稱(chēng)常量(新)。
* 生成Spring配置文件(支持事務(wù)申明)。
* 生成xwork配置文件(增加多包及spring屬性支持)。
* 驗(yàn)證資源冗余及缺失。
先吧PPT放出來(lái),如果有人(包括我自己)能用上再吧代碼整理一下,放出來(lái)。
ppt下載:
http://www.tkk7.com/Files/jindw/codegen.rar
裝飾引擎簡(jiǎn)介:
系統(tǒng)默認(rèn)的裝飾引擎為:org.xidea.decorator.DecoratorEngine。
JSI裝載后,將做如下操作:
- 判斷有無(wú)裝飾器命名空間聲明(xmlns:d= "http://www.xidea.org/taglib/decorator")
- 若有,將在文檔裝載結(jié)束后,啟動(dòng)裝飾引擎,初始化當(dāng)前可用的裝飾提供者表。(裝飾提供者是一個(gè)JavaScript包,在注冊(cè)這種裝飾包時(shí)可同時(shí)指定他的別名,別名*表示默認(rèn)包)
- 遍歷當(dāng)前文檔,凡是該命名空間的節(jié)點(diǎn),都被看作需要裝飾的元素。若當(dāng)前文檔存在裝飾元素,啟用遮罩(關(guān)機(jī)效果),頁(yè)面將不可操作(仍可查閱)。
- 查找裝飾元素對(duì)應(yīng)的裝飾類(lèi)(通過(guò)tagName判斷類(lèi)名),采用異步方式動(dòng)態(tài)裝載這些裝飾器類(lèi)(不會(huì)裝載到全局空間),并更新當(dāng)前進(jìn)度信息,同時(shí)設(shè)置裝飾器之間的關(guān)系(parent,children)。
- 以深度遍歷的方式遍歷這些節(jié)點(diǎn),注冊(cè)組件(以后可以通過(guò)$JSI.getComponent函數(shù)獲取裝飾器對(duì)象),依次執(zhí)行他們的before操作,和decorate操作。
- 完成裝飾,取消遮罩,頁(yè)面進(jìn)入可用狀態(tài)。
裝飾器規(guī)范簡(jiǎn)介:
裝飾器指的是所有擁有decorate成員方法的類(lèi)。一般來(lái)說(shuō),可將一組裝飾器歸為同一個(gè)包中(太復(fù)雜的裝飾器,可將具體邏輯放置在其他包中),能后在配置文件中定義裝飾包。
scripts/config.js $JSI.addDecoratorProvider("org.xidea.decorator","xidea","*");
裝飾器類(lèi)包含兩個(gè)方法before、docorate分別在遍歷前(子節(jié)點(diǎn)未裝飾)和遍歷后(子節(jié)點(diǎn)裝飾完成)調(diào)用。
同時(shí),裝飾引擎遍歷時(shí)還將注入如下三個(gè)屬性:
- parent:父裝飾器
- children:子裝飾器集合
- attributes:裝飾器屬性集對(duì)象(只有一個(gè)成員函數(shù):get(attrName) )
JSI現(xiàn)有裝飾器集合簡(jiǎn)介
目前JSI2最高版本2.0預(yù)覽版 (2007-04-16)包含如下裝飾器:
- DatePicker
日期選擇控件,參照xul datepicker標(biāo)簽,支持彈出方式(默認(rèn)值 type='pop'),和內(nèi)嵌式(type='grid')
- Editor
編輯器控件,參照xul editor標(biāo)簽
- Spinner
Spinner控件(window時(shí)間日期管理中,年份調(diào)節(jié)的控件),參照backbase 的 Spinner標(biāo)簽
- TabBox、Tabs、Tab、TabPanels、TabPanel
TabBox(標(biāo)簽頁(yè))控件,參照xul tabbox標(biāo)簽
- Code
代碼語(yǔ)法高亮顯示控件,參照SyntaxHighlighter的顯示風(fēng)格
- Include
片斷包含標(biāo)簽,支持xpath選取文檔片斷,支持xslt轉(zhuǎn)換
這些裝飾器的演示見(jiàn):
http://www.xidea.org/project/jsi/decorator/index.html
目前JSI自帶的裝飾器不夠豐富,而且都還是初級(jí)階段,不夠完善。現(xiàn)在發(fā)布的這些裝飾器,主要是為了演示JSI的工作方式,編碼風(fēng)格,希望能吸引第三方團(tuán)隊(duì)、公司在這個(gè)基礎(chǔ)上開(kāi)發(fā)出自己的更加實(shí)用的裝飾器集合。
JSI及其裝飾引擎采用LGPL協(xié)議。可以商業(yè)應(yīng)用,當(dāng)能,更希望能開(kāi)源。
目前就我一人之力,開(kāi)發(fā)一套完整的裝飾器,尚需時(shí)日,這次將這個(gè)半成品拿出來(lái)演示,主要是為了展示一下jsd的風(fēng)格,希望能吸引其他開(kāi)發(fā)者,共同參與這個(gè)工程,有興趣豐富JS自帶I裝飾器集合的網(wǎng)友,請(qǐng)msn與我聯(lián)系:jindw◎xidea。org
JSI組件模型是一種用來(lái)裝飾簡(jiǎn)單html元素的框架,使用簡(jiǎn)單的xml標(biāo)記,標(biāo)識(shí)其裝飾行為,比如將一個(gè)普通的input裝飾成一個(gè)日期輸入控件,將一
個(gè)html ul標(biāo)記裝飾成菜單或樹(shù),將一個(gè)textarea裝飾成一個(gè)代碼語(yǔ)法高亮顯示區(qū)域,或一個(gè)wysiwyg html編輯器。
JSI啟動(dòng)后將自動(dòng)檢查decorator標(biāo)記,構(gòu)建層次結(jié)構(gòu),自動(dòng)做相關(guān)類(lèi)的尋找、導(dǎo)入和裝飾操作;實(shí)現(xiàn)零腳本代碼的web富客戶(hù)端編程。
代碼示例:
- 日期選擇器 (DatePicker):
<d:datepicker>
<input type="text" name="test2" />
</d:datepicker>
- 編輯器示例 (Editor):
<d:editor>
<textarea name='editorText'>This is some <strong>sample text</strong>. You are using <a
href="http://www.fckeditor.net/">FCKeditor</a>.</textarea>
</d:editor>
- Spinner控件(Spinner 類(lèi)似window時(shí)間日期管理中,年份調(diào)節(jié)的控件):
<d:spinner start='0' end='8' step='2'>
<input type="text" name="test2" value='0' />
</d:spinner>
- 客戶(hù)端包含(Include):
<d:include url='menu.xml' xslt="menu.xsl"></d:include>
- 代碼語(yǔ)法高亮顯示控件(Code):
<d:code language="js">
<textarea>alert(‘Hello World’)</textarea>
</d:code>
- 標(biāo)簽頁(yè)控件(TabBox參照xul tabbox標(biāo)簽):
<d:tabbox>
<d:tabs>
<d:tab>tab1</d:tab>
<d:tab>tab2</d:tab>
<d:tab>tab3</d:tab>
</d:tabs>
<d:tabpanels>
<d:tabpanel>content1</d:tabpanel>
<d:tabpanel>content2</d:tabpanel>
<d:tabpanel>content3</d:tabpanel>
</d:tabpanels>
</d:tabbox>
- 綜合示例:
來(lái)一個(gè)復(fù)雜一點(diǎn)的完整的例子,以日期選擇控件的演示頁(yè)面為例
頁(yè)面上有: 標(biāo)簽頁(yè)裝飾器(TabBox….)、源代碼高亮顯示裝飾器(Code)、日期選擇裝飾器(DatePicker)、包含裝飾器(Include)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:d="http://www.xidea.org/taglib/decorator" xml:lang="zh_CN"
lang="zh_CN">
<head>
<script src="../scripts/boot.js"></script>
<title>DatePicker 示例</title>
</head>
<body>
<h2>DatePicker 示例</h2>
<!-- 開(kāi)始標(biāo)簽頁(yè)裝飾器 -->
<d:tabbox>
<d:tabs>
<d:tab>效果</d:tab>
<d:tab>代碼</d:tab>
</d:tabs>
<d:tabpanels>
<d:tabpanel>
<!-- 開(kāi)始日期裝飾器(內(nèi)嵌式) -->
<d:datepicker type='grid'>
<input type="text" name="test1" />
</d:datepicker>
<!-- 開(kāi)始日期裝飾器(彈出式) -->
<d:datepicker>
<input type="text" name="test2" />
</d:datepicker>
</d:tabpanel>
<d:tabpanel>
<!-- 開(kāi)始代碼高亮顯示 -->
<d:code language="xml">
<textarea>
<!-- 開(kāi)始日期裝飾器(內(nèi)嵌式) -->
<d:datepicker type='grid'>
<input type="text" name="test1" />
</d:datepicker>
<!-- 開(kāi)始日期裝飾器(彈出式) -->
<d:datepicker>
<input type="text" name="test2" />
</d:datepicker></textarea>
</d:code>
</d:tabpanel>
</d:tabpanels>
</d:tabbox>
<select style="margin-left:120px"><option>彈出的datepicker 可覆蓋IE select</option></select>
<hr />
<!-- 開(kāi)始Include裝飾器,包含裝飾器菜單 -->
<d:include url='menu.xml' xslt="menu.xsl"></d:include>
</body>
</html>
裝飾結(jié)果:
云想衣裳花想容--JSI組件模型介紹(二)已經(jīng)發(fā)布,那里有裝飾過(guò)程及其原理的介紹:
http://www.javaeye.com/topic/71425
眾所周知, Scriptaculous所依賴(lài)的Prototype庫(kù)與jQuery存在沖突。所以同時(shí)使用比較困難。
JSI針對(duì)每一個(gè)裝載的腳本都有完全獨(dú)立的執(zhí)行上下文。所以這個(gè)問(wèn)題能在JSI上徹底解決。
下面的例子,我們將在同一個(gè)頁(yè)面上同時(shí)使用Scriptaculous和 jQuery 類(lèi)庫(kù)。證實(shí)一下JSI隔離沖突功能。
示例頁(yè)面(hello-jquery-aculo.html):
<html>
<head>
<title>Hello jQuery And Scriptaculous</title>
<!-- 加入引導(dǎo)腳本 -->
<script src="../scripts/boot.js"></script>
<script>
//導(dǎo)入jQuery
$import("org.jquery.$");
//導(dǎo)入Scriptaculous
$import("us.aculo.script.Effect");
$(document).ready(function(){
//使用jQuery添加一段問(wèn)候語(yǔ)
$("<p id='helloBox' style='background:#0F0;text-align:center;font-size:40px;cursor:pointer;'>Hello jQuery And Scriptaculous</p>") .appendTo('body');
$('#helloBox').ready(function(){
//使用Scriptaculous高亮顯示一下剛才添加的內(nèi)容
new Effect.Highlight('helloBox');
}).click(function(){
//當(dāng)用戶(hù)單擊該內(nèi)容后使用jQuery實(shí)現(xiàn)漸出
$('#helloBox').fadeOut();
});
});
</script>
</head>
<body>
<p>文檔裝載后,jQuery將在后面添加一段問(wèn)候語(yǔ);并使用Scriptaculous高亮顯示(Highlight);在鼠標(biāo)點(diǎn)擊后在使用jQuery漸出(fadeOut)。</p>
</body>
</html>
Java的成功,離不開(kāi)它那個(gè)龐大的類(lèi)庫(kù),不單是sun的類(lèi)庫(kù),很多細(xì)節(jié)的實(shí)現(xiàn)都取自第三方(如xml解析采用Apache的實(shí)現(xiàn))。
JSI暫時(shí)不大算編寫(xiě)豐富的公共API,但是我們可以集成其他成熟的類(lèi)庫(kù),同時(shí)隔離他們的依賴(lài),隔離各個(gè)腳本的執(zhí)行上下文,消除命名沖突的危險(xiǎn)。
這里我們?cè)敿?xì)介紹一個(gè)復(fù)雜一點(diǎn)的實(shí)例:類(lèi)似Windows XP文件瀏覽器左側(cè)的滑動(dòng)折疊面板(任務(wù)菜單)效果。
我們先集成Scriptaculous Effect類(lèi)庫(kù),并且在這個(gè)基礎(chǔ)上按我個(gè)人的習(xí)慣對(duì)一個(gè)面板折疊效果做一個(gè)簡(jiǎn)單的封裝,展示框架的類(lèi)庫(kù)封裝功能。
1。集成Scriptaculous類(lèi)庫(kù):
這里我們不做過(guò)多介紹,詳細(xì)情況請(qǐng)參考集成實(shí)戰(zhàn);我們發(fā)布的版本中已經(jīng)把Scriptaculous放置于us.aculo.script包中,您可以把這些作為系統(tǒng)內(nèi)置的類(lèi)庫(kù)使用。
2。編寫(xiě)我們的折疊面板函數(shù)(example/effect.js):
/**
* 滑動(dòng)面板實(shí)現(xiàn).
* 當(dāng)指定元素可見(jiàn)時(shí),將其第一個(gè)子元素向上滑動(dòng)至完全被遮掩(折疊)。
* 當(dāng)指定元素不可見(jiàn)時(shí),將其第一個(gè)子元素向下滑動(dòng)至完全顯示(展開(kāi))。
*/
function slidePanel(panel){
panel = $(panel);
if(panel.style.display=='none'){
//調(diào)用Scriptaculous Effect的具體滑動(dòng)展開(kāi)實(shí)現(xiàn)
new Effect.SlideDown(panel);
}else{
//調(diào)用Scriptaculous Effect的具體滑動(dòng)閉合實(shí)現(xiàn)
new Effect.SlideUp(panel);
}
}
3。編寫(xiě)包定義腳本(example/__$package.js):
//添加slidePanel(滑動(dòng)面板控制)函數(shù)
this.addScript("effect.js","slidePanel",null);
//給effect.js腳本添加對(duì)us.aculo.script包中effects.js腳本的裝載后依賴(lài)this.addScriptDependence("effect.js",
"us/aculo/script/effects.js",false);
4。在網(wǎng)頁(yè)上運(yùn)用上面的類(lèi)庫(kù):
<html>
<head>
<title>重用aculo Effect腳本實(shí)例</title>
<link rel="stylesheet" type="text/css" href="/styles/default.css" />
<script src="/scripts/boot.js"></script>
<script>
$import("example.slidePanel");
</script>
</head>
<body>
<div class="menu_header"
onclick="slidePanel('menu_block1')">
面板 1
</div>
<div class="menu_block" id="menu_block1">
<ul>
<li>text1</li>
<li>text2</li>
<li>text3</li>
</ul>
</div>
</body>
</html>
onclick="slidePanel('menu_block1')"這個(gè)事件函數(shù)將在我們點(diǎn)擊面板標(biāo)題時(shí)觸發(fā),能后會(huì)調(diào)用Scriptaculous Effect的具體實(shí)現(xiàn)去實(shí)現(xiàn)我們需要的滑動(dòng)折疊功能。
壁立千仞 無(wú)欲則剛――控制依賴(lài)
java可以隨意的使用第三方類(lèi)庫(kù),可是JavaScript卻沒(méi)那么幸運(yùn),隨著類(lèi)庫(kù)的豐富,煩雜的依賴(lài)關(guān)系和可能的命名沖突將使得類(lèi)庫(kù)的發(fā)展越來(lái)越困難。程序的易用性也將大打折扣。
命名沖突的危險(xiǎn)無(wú)形的增加你大腦的負(fù)擔(dān);隨著使用的類(lèi)庫(kù)的增加,暴露的依賴(lài)也將隨之增加,這是復(fù)雜度陡增的極大禍根,將使得系統(tǒng)越來(lái)越復(fù)雜,越來(lái)越難以控制。潛在的問(wèn)題越來(lái)越多,防不勝防。
JSI的出現(xiàn),可以解決上述問(wèn)題,我們建議類(lèi)庫(kù)的開(kāi)發(fā)者將自己類(lèi)庫(kù)的依賴(lài)終結(jié)在自己手中,避免依賴(lài)擴(kuò)散,以提高類(lèi)庫(kù)的易用性。
同樣使用上面的例子,假如我們想拋開(kāi)JSI,實(shí)現(xiàn)同樣的功能,那我們的頁(yè)面代碼將是(類(lèi)庫(kù)代碼不用改動(dòng)):
<html>
<head>
<title>重用aculo Effect腳本實(shí)例</title>
<link rel="stylesheet" type="text/css" href="/styles/default.css" />
<!--
<script src="/scripts/boot.js"></s cript>
<script>
$import("example.slidePanel");
</sc ript>
-->
<script src="/scripts/net/conio/prototype/v1_5/prototype.js">
</script>
<script src="/scripts/us/aculo/script/v1_7/effects.js">
</script>
<script src="/scripts/us/aculo/script/v1_7/builder.js">
</script>
<script src="/scripts/example/effect.js">
</script>
</head>
<body>
<div class="menu_header"
onclick="slidePanel('menu_block1')">
面板 1
</div>
<div class="menu_block" id="menu_block1">
<ul>
<li>text1</li>
<li>text2</li>
<li>text3</li>
</ul>
</div>
</body>
</html>
這個(gè)例子的html代碼明顯比上面的復(fù)雜了,一堆堆的script標(biāo)簽,而且還是有序的;還出現(xiàn)在頁(yè)面上,重構(gòu)起來(lái)也極其麻煩。
可以看出,JSI的加入可以讓類(lèi)庫(kù)更加易用,html代碼更為簡(jiǎn)潔,最終用戶(hù)已經(jīng)不必關(guān)心所用類(lèi)庫(kù)的依賴(lài)了。
JSI中每一個(gè)腳本有一個(gè)單獨(dú)的執(zhí)行上下文。各個(gè)腳本頂部變量你可以隨便使用,不必?fù)?dān)心不同腳本中的命名沖突,不會(huì)污染全局變量空間,這種方式可以用于解
決某些類(lèi)庫(kù)間變量沖突的問(wèn)題(如jQuery和Prototype的$函數(shù))。我們甚至可以做到同一個(gè)頁(yè)面上間接加載同一種類(lèi)庫(kù)的兩個(gè)不同版本,不相互影
響。
使用JSI后,很多細(xì)節(jié)我們可以在包中封裝掉,不需要告訴類(lèi)庫(kù)使用者太多。大大增加類(lèi)庫(kù)的易用性。同時(shí),類(lèi)庫(kù)封裝的支持可以讓我們?cè)诘谌綆?kù)的基礎(chǔ)上輕松的按自己的喜好編寫(xiě)自己的類(lèi)庫(kù),同時(shí)避免依賴(lài)擴(kuò)散造成的復(fù)雜度增加。
使用JSIntegration唯一多出的負(fù)擔(dān)就是編寫(xiě)包定義文件,不過(guò)想想這種定義文件可是一勞永逸的(以后就不需要每次導(dǎo)入腳本的時(shí)候都小心翼翼的判
斷那個(gè)腳本先導(dǎo)入那個(gè)后導(dǎo)入,有那些間接使用到的類(lèi)庫(kù)需要導(dǎo)入,等等),而且有了包結(jié)構(gòu)后對(duì)于代碼組織、重用,以及文檔的編寫(xiě)閱讀,都將非常有利。
何謂安需裝載?
腳本程序一般都是下載后執(zhí)行
,當(dāng)腳本庫(kù)非常龐大時(shí),一次性下載起來(lái)非常費(fèi)時(shí),傳統(tǒng)的解決方式是,按功能模塊把腳本寫(xiě)在不同的文件中,頁(yè)面上手動(dòng)加入script標(biāo)簽裝載指定內(nèi)容,但
是這有一些缺點(diǎn),類(lèi)庫(kù)的使用者需要知道沒(méi)個(gè)腳本之間的關(guān)系,順序要求等等,而不可能要求每個(gè)類(lèi)庫(kù)使用者都對(duì)其非常熟悉,出錯(cuò)的可能性很大。于是很多框架開(kāi)
始支持導(dǎo)入指令,想使用什么一個(gè)導(dǎo)入函數(shù)就完了,不必一堆堆的script文件,不用小心翼翼的關(guān)注著他們的依賴(lài)關(guān)系。
安需裝載可分如下三種模式:
- 即時(shí)同步按需裝載(阻塞,JSI、JSVM、dojo)。
最簡(jiǎn)單的按需裝載實(shí)現(xiàn),通過(guò)XMLHttpRequest同步裝載腳本文件實(shí)現(xiàn)。問(wèn)題是,瀏覽器使用這種方式同步獲取資源時(shí)將導(dǎo)致瀏覽器阻塞:停止響應(yīng)用戶(hù)事件、停止頁(yè)面重畫(huà)操作。所以,雖然編程最為簡(jiǎn)單,但是用戶(hù)體驗(yàn)最差。
- 異步按需裝載(無(wú)阻塞,JSI2.0+)。
異步導(dǎo)入,不必多做解釋?zhuān)脩?hù)體驗(yàn)好,但是因?yàn)槠洚惒教卣鳎幚砥饋?lái)比較麻煩。
- 延遲同步按需裝載(無(wú)阻塞,JSI2.0+)。
JSI通過(guò)動(dòng)態(tài)預(yù)裝載功能實(shí)現(xiàn)的一種同步獲取資源的方法,雖然也是同步,但沒(méi)有阻塞,可以算時(shí)兼顧易用性和用戶(hù)體驗(yàn)的機(jī)決方按。缺點(diǎn)時(shí)有一定延遲,當(dāng)前腳本標(biāo)簽中不可用。
使用方法(JSI示例)
以一個(gè)代碼語(yǔ)法著色程序?yàn)槔?br>
類(lèi)庫(kù)位置:example/
codedecorator/code.js
頁(yè)面位置:example/xxx.html
- 即時(shí)同步按需裝載
$import("example.codedecorator.Code");
var code1 = new Code();
code1.id = "libCode";
code1.decorate();
- 異步按需裝載
$import("example.codedecorator.Code",function(Code){
var code1 = new Code();
code1.id = "libCode";
code1.decorate();
})
- 延遲同步按需裝載(無(wú)阻塞,JSI2.0+)。
<script>"../scripts/boot.js"></script>
<script>
$import("example.codedecorator.Code",true);
</script>
<script>
var code1 = new Code();
code1.id = "libCode";
code1.decorate();
</script>
示例說(shuō)明:
在線測(cè)試
http://jsintegration.sourceforge.net/example/code.html
http://www.xidea.org/project/jsi/example/code.html
參考:
JSI 導(dǎo)入函數(shù): function $import(path, callbackOrLazyLoad, target )
這個(gè)問(wèn)題算是個(gè)老問(wèn)題了。
所以,標(biāo)題加上一個(gè)再字。
我主要說(shuō)一下模擬這個(gè)事件時(shí)候容易出現(xiàn)的問(wèn)題。
對(duì)于FF,Opera9,原生DOMContentLoad支持,就不說(shuō)了,最頭疼的是IE。
我最初考慮這個(gè)問(wèn)題的時(shí)候,想到的是document的readyState屬性。
偷窺一下Dojo的源碼,發(fā)現(xiàn)它也是基于這個(gè)屬性去做的,那時(shí),我基本就認(rèn)準(zhǔn)了這個(gè)方法。
于是再后來(lái)JSI1和JSI2早期的預(yù)覽版本中,都是基于這個(gè)屬性做的,后來(lái),有個(gè)朋友向我反應(yīng),說(shuō)JSI的裝飾引擎在IE上啟動(dòng)比FF慢很多,我當(dāng)時(shí)就猜測(cè),是否是這個(gè)DOMContentLoad的問(wèn)題。
經(jīng)過(guò)測(cè)試,發(fā)現(xiàn),確實(shí),readyState必須等待圖片裝載完成之后才能置為complete。
于是到網(wǎng)上搜索一下其他辦法,最終 Dean Edwards的blog上描述的一個(gè)基于script defer屬性的解決辦法勝出:http://dean.edwards.name/weblog/category/dom/onload/
不過(guò),使用document.write打印一段腳本,我真的不喜歡:(
在評(píng)論里面我們可以看到一些其他的建議,有人認(rèn)為 readyState == 'complete' 加
readyState==‘interactive’這個(gè)狀態(tài)可以準(zhǔn)確模擬DOMContentLoad。我開(kāi)始簡(jiǎn)單測(cè)試一下,貌似可行,但是后來(lái)發(fā)現(xiàn)
readyState==‘interactive’可能受alert等函數(shù)影響,就是說(shuō),一般情況下,readyState==
‘interactive’時(shí),dom是裝載完了的,但是,當(dāng)你文檔裝載過(guò)程中,調(diào)用了alert函數(shù),那么,readyState將提前置為
‘interactive’。
總之,目前來(lái)說(shuō),我知道的,只有兩個(gè)辦法可以真正實(shí)現(xiàn)IE上模擬DOMContentLoad
1.htc ondocumentready(需要額外的HTC文件)
2.script defer(必須使用document.write打印一段腳本標(biāo)記,jquery目前采用的方式)
最常見(jiàn)的一個(gè)錯(cuò)誤:
document.readyState(Dojo目前(0.4.1)采用的方式)
再說(shuō)一下JSI的DOMContentLoad實(shí)現(xiàn)的使用接口。
js.html.EventUtil.addDOMReadyListener(<Function>listener ,<boolean>runAnyCase )
第二個(gè)參數(shù)用于確保listener 在任何時(shí)候都會(huì)被調(diào)用(FF DOMContentLoad事件如果在事件發(fā)生之后設(shè)置listener是無(wú)效的)
裝載效率測(cè)試
測(cè)試頁(yè)面見(jiàn):test/load-eff-test.html
為了測(cè)試結(jié)果更顯客觀,我選擇了第三方類(lèi)庫(kù)的裝載測(cè)試:
'com.yahoo.yui.*',
'net.conio.prototype.*',
'net.fckeditor.*',
'org.jquery.*',
'us.aculo.script.*'
共22個(gè)腳本文件(對(duì)于JSI來(lái)說(shuō)還有諾干包定義文件)。
FF2:
標(biāo)記導(dǎo)入時(shí)間(原始方式):469,469,1047,484,484,437,469,484
同步導(dǎo)入時(shí)間:469,453,484,437,469,453
延遲導(dǎo)入時(shí)間:921,765,891,906,953,906,922
異步導(dǎo)入時(shí)間:859,1093,1141,1031,1641,1125,1078,1093,1157,1141
IE7:
標(biāo)記導(dǎo)入時(shí)間:343,297,297,344,328,328
同步導(dǎo)入時(shí)間:281,250,235,235,234,234,250,265
延遲導(dǎo)入時(shí)間:922,422,406,391,391,391,407,391
異步導(dǎo)入時(shí)間:625,672,672,703,703,672,703,704,688
運(yùn)行時(shí)間測(cè)試
測(cè)試腳本管理后對(duì)新能的影響,影響因素有:全局變量和局部變量的查找時(shí)間差異,eval的腳本和script標(biāo)記直接插入的腳本的可能差異。(這
個(gè)測(cè)試不具有普遍性,這里我主要是測(cè)試了一下瀏覽器對(duì)局部變量的訪問(wèn)速度【JSI里面訪問(wèn)變量都是裝載單元內(nèi)的局部變量】,所以故意測(cè)試了大量局部變量訪
問(wèn)的操作)
測(cè)試頁(yè)面見(jiàn):test/runtime-eff-test.html
FF2:
jsiTime: 845, 927, 598, 687, 764,
scriptTime: 1432, 950, 1305, 1278, 1219,
evalTime: 1644, 1373, 1322, 1186, 1360,
execTime: 0
dscriptTime: 1432, 950, 1305, 1278, 1219,
IE7:
jsiTime: 295, 205, 157, 315, 156, 142, 375, 328, 172, 172,
scriptTime: 172, 172, 189, 140, 251, 187, 217, 203, 172, 234,
evalTime: 236, 249, 139, 172, 281, 171, 172, 108, 436, 359,
execTime: 219, 234, 314, 157, 220, 266, 204, 234, 187, 95,
dscriptTime: 187, 265, 294, 326, 187, 328, 141, 221, 127, 249,
上面的基數(shù)太小,隨機(jī)誤差太大,調(diào)整原始數(shù)據(jù)從新測(cè)試一遍jsiTime和scriptTime
jsiTime: 576, 658, 688, 703, 611, 608,
scriptTime: 706, 608, 562, 547, 655, 657,
總結(jié):
JSI的裝載性能表現(xiàn)不錯(cuò),完全不必計(jì)較。
托管代碼的運(yùn)行性能也沒(méi)有太大區(qū)別,不過(guò),因?yàn)椤SI托管腳本使用的變量基本都是裝載單元內(nèi)的局部變量(本地聲明變量,或者外部依賴(lài)的引用或值拷貝),所以,對(duì)于FF這類(lèi)局部變量比全局變量訪問(wèn)速度快不少的解釋引擎,JSI托管腳本可以達(dá)到更好的運(yùn)行效率。
有個(gè)奇怪的問(wèn)題,JSI在裝載類(lèi)庫(kù)時(shí),與傳統(tǒng)模式相比,肯定增加了些額外的運(yùn)算,但是,貌似JSI的同步裝載模式下,裝載腳本的耗時(shí)比傳統(tǒng)模式還少(IE 表現(xiàn)明顯)?為何?
歡迎大家對(duì)這奇怪的現(xiàn)象提出自己的猜想,我稍后貼出我對(duì)此問(wèn)題的看法^_^
這次發(fā)布的JSI2Alpha相對(duì)于以前的預(yù)覽版本,做了一次全面的重構(gòu);同時(shí)對(duì)API做了些簡(jiǎn)化。
目前JSI2的公開(kāi)API有:
/* 導(dǎo)入函數(shù) */
$import(<string>path,<boolean|Function>callbackOrLazyLoad[可選參數(shù)],<Object>target[可選參數(shù)])
/* 日志設(shè)置相關(guān) */
$JSI.setDefaultLogLevel(level)
$JSI.setLogLevel(pathPattern,level)
/* 裝飾引擎相關(guān)函數(shù) */
$JSI.addDecoratorProvider(pkg,alias…) //添加裝飾包.
$JSI.decorate ( ) //準(zhǔn)備執(zhí)行裝飾器任務(wù),一般在配置文件(config.js)中調(diào)用.
/* 用于包定義的Package成員函數(shù),在__package__.js中調(diào)用(this指向當(dāng)前package對(duì)象) */
this.addScript(scriptPath,objectNames)//添加腳本及其聲明的對(duì)象(函數(shù)、方法名).
this.add*Dependence(thisPath,targetPath,beforeLoad)//添加腳本依賴(lài).
this.setImplementation(realPackage)//設(shè)置具體實(shí)現(xiàn)包(當(dāng)前包只是其別名,并無(wú)任何內(nèi)容)。
我們會(huì)盡量將JSI做成與具體功能無(wú)關(guān)(專(zhuān)著于腳本管理)。
對(duì)于js.*.*這個(gè)類(lèi)庫(kù),做了些精簡(jiǎn)。
只保留下列元素
#js.html //保留這個(gè)包,因?yàn)檫@些實(shí)在太常用了。
* BrowserInfo
* EventUtil
* StyleUtil
#js.util//保留這個(gè)包主要因?yàn)楫惒窖b載用到這些類(lèi)庫(kù)
* LoadTask
* Request
* ScriptLoadTask
* TaskQueue
發(fā)布文件說(shuō)明:
自該版本啟,source目錄將不再打包。
但是在scripts目錄下新增boot-with-source.js文件,該文件中包含全部源代碼的數(shù)據(jù)。
里面編碼的源代碼可以通過(guò)我們的文檔工具查看。讓大家習(xí)慣一下這個(gè)工具的使用:)
JSA1beta:增加了對(duì)JSI2的編譯支持,同時(shí)對(duì)于普通腳本的壓縮,也增加了一些功能:
1. ant task 增加多文件分組合并。
2. swing ui 修正文件編碼的bug。
下載:
javaeye group: http://jsi.group.javaeye.com/shares
sourceforge: <系統(tǒng)最近好像有問(wèn)題,我的文件一直沒(méi)能上傳成功,要過(guò)一段時(shí)間再說(shuō)> 。。。。。
今天抽空測(cè)試了一下JSI當(dāng)前狀態(tài)的瀏覽器兼容性,一個(gè)頭疼的問(wèn)題困擾了很久。
找出問(wèn)題出自,懷疑是一個(gè)opera的bug。
function test(x){
try{
if(x){
return 1;
}else{
return 2;
}
}catch(e){
x=1;
}finally{
x=2;
}
}
語(yǔ)法檢查就通不過(guò),報(bào)告錯(cuò)誤:
le://localhost/D:/eclipse/workspace/JSI/web/scripts/core.js
Event thread: BeforeExternalScript
opera8報(bào)錯(cuò),opera9好像就沒(méi)有這個(gè)問(wèn)題。
貼出來(lái),讓有類(lèi)似問(wèn)題的人省點(diǎn)心。
剛發(fā)布JSA的webstart版,順便吧這個(gè)古董級(jí)別的小程序也發(fā)布一下。
僅供那些和我一樣棋術(shù)平平的無(wú)聊人士打發(fā)時(shí)間。
高手就不必了:)
當(dāng)能,如果是想找個(gè)地方出出氣,也可以,呵呵。
http://www.xidea.org/webstart/chess.jnlp
沒(méi)有棋譜,所以,開(kāi)局的棋力很差。中局還行。