<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    爪哇東南的自留地

    學(xué)習(xí)探討開源和web開發(fā)

    導(dǎo)航

    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    統(tǒng)計

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    相冊

    收藏夾

    life

    technique

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    2006年10月2日 #

    數(shù)碼攝影中的光及用光技巧

         摘要: 大家都知道,攝影是光的藝術(shù)!沒有光線,就沒有攝影;用光不當(dāng),就得不到一幅滿意的照片。因此,光是攝影的基礎(chǔ),有了它,感光材料才有感光的可能;有了它,物體才能顯現(xiàn)出形態(tài)、色彩和質(zhì)感。 ??? 布光,則是攝影中的一項創(chuàng)造性工作,它體現(xiàn)著一個攝影師的個性和風(fēng)格,也關(guān)系到一幅作品的成敗。 ??? 從某種意義上講,不管是攝...  閱讀全文

    posted @ 2006-10-02 14:32 ericli 閱讀(1549) | 評論 (2)編輯 收藏

    2006年9月27日 #

    數(shù)碼攝影入門之六 名家名言

    根據(jù)
    美國攝影家維利·奎克的看法,幾乎所有的人都能夠通過應(yīng)用一些基本法則,達(dá)到具有相當(dāng)水平的攝影構(gòu)圖能力。為此,他提出了一些簡單的方法。他認(rèn)為,依據(jù)這些方法,任何人都能在短時間內(nèi)學(xué)會拍出較好的照片。

    有些人或許對構(gòu)圖有天賦。不過,根據(jù)美國攝影家維利·奎克的看法,幾乎所有的人都能夠通過應(yīng)用一些基本法則,達(dá)到具有相當(dāng)水平的攝影構(gòu)圖能力。為此,他提出了一些簡單的方法。他認(rèn)為,依據(jù)這些方法,任何人都能在短時間內(nèi)學(xué)會拍出較好的照片。?

    維利·奎克指出,攝影者最易犯的錯誤是拍攝點(diǎn)取得過高,與被攝體離得太遠(yuǎn),致使畫面出現(xiàn)各種各樣與拍攝目的毫無關(guān)系的東西。

    他說:“請記住,畫家是 把東西畫進(jìn)畫面,而攝影者則是從畫面去掉一些東西。” 他說:“一張照片應(yīng)該只有一個趣味中心,畫面上不能有無用的東西。如果你對某個物體是否有助于畫面抱有懷疑,你就應(yīng)盡可能地把它放棄掉。” 這里就是人們常說的攝影是“減法的藝術(shù)”

    奎克認(rèn)為:“這并不是說,趣味中心非得準(zhǔn)確地置于交叉點(diǎn)上不可。正因?yàn)槿绱耍瑢?shí)際上趣味中心常出現(xiàn)在交叉點(diǎn)附近。”?

    奎克指出:“每一幅照片都應(yīng)保持一定的平衡。這就是說,對主要被攝體的安排,不能使畫、面出現(xiàn)向分量大的一邊傾倒。但平衡并不意味著將兩個同樣大小和同等形狀的東西置于對稱的位置。這里的關(guān)系,只要你看一下在玩蹺蹺板的孩子就知道了。蹺蹺板兩邊的孩子,小些的一個必定坐在離中央遠(yuǎn)些的地方,而大的孩子肯定坐在靠近中央的地方。”?

    奎克認(rèn)為:“把突出的線條安排,指向趣味中心,是拍攝一幅悅目照片的另一個要素。這些線條被稱為主導(dǎo)線,有效地利用主導(dǎo)線,可以創(chuàng)造出驚人的照片。把主導(dǎo)線安排成對角線,會產(chǎn)生有力的動感。?

    “線條常常在照片中提供一個邊框。這可以通過選擇視點(diǎn)來進(jìn)行,例如在樹下通過樹枝框住畫面上的被攝主體。此時通常使用小光圈,以使整幅照片清晰。這樣做,也有可能使邊框過于突出,但安排適當(dāng),會得到好照片。?
    “在一幅照片中,地平線的位置會給人以強(qiáng)烈的印象。拍攝時,地平線要盡量避免處在照片的等比線上,因?yàn)檫@樣做會把照片均分為兩半,給人以呆板的感覺。?

    地平線處在畫面下方,會給人以寧靜的感覺,而處于上方,給人的感覺則是活潑、有力的。 “此外,橫幅畫面可以產(chǎn)生安寧、平靜的感覺,而豎直畫面則會產(chǎn)生動態(tài)效果。”?

    奎克認(rèn)為,以上方法如果運(yùn)用得好,你的照片將會出現(xiàn)明顯的改觀,而且隨著時間的推移,你很快就會學(xué)會鑒賞構(gòu)圖,從而為你增添攝影的樂趣。?

    達(dá)柯 認(rèn)為,有時“如果線條與視覺產(chǎn)生了共鳴,一簇線條本身就能成為一個主體”。

    美國攝影家L.小雅各希斯認(rèn)為:“構(gòu)圖是從攝影者的心靈的眼睛做起的。構(gòu)圖的過程也被稱為‘預(yù)見’,就是在未拍攝某一物體之前或正在拍攝的時候,就能在腦海中形成一個圖像或印象。通過經(jīng)常析自己和別人的作品的構(gòu)圖,就會使自己的這種預(yù)見本領(lǐng)更加嫻熟,變成一種本能。”這就是我常說的用腦子拍照。

    線條構(gòu)成畫面

    奧地利攝影家伊涅斯特·哈斯對此也有同感,對于構(gòu)圖,他己達(dá)到手中無劍,劍在心中的境界,他認(rèn)為、“構(gòu)圖在于平衡,每個人對平衡的處理都各有不同。”正如同武功達(dá)到最高境界時,已沒有招式名稱,只憑自己的功力去化解。他認(rèn)為:“你越能忘記你的器材,就越能集中你的題材和構(gòu)圖,這時相機(jī)只是你眼睛的延續(xù),再沒有其他意義。” 小雅各布斯還認(rèn)為:“構(gòu)圖的最基本的因素是線條、形式、質(zhì)感以及這些因素之間的空間。當(dāng)然色彩同樣也是不可忽略的因素。會聚的線條一般能說明透視關(guān)系,但并不是所有的照片都非要表現(xiàn)出透視的深度不可。許多杰出的作品都是平面圖案。在取景器中的某個景物或人物的肖像,都是根據(jù)攝影者個人的感受進(jìn)行安排的。就是所謂攝影里所有的控制是服務(wù)于你想表達(dá)的情緒。

    色彩的平衡很重要

    “在大多數(shù)情況下,每幅照片中都有一個或一組形狀或形式起主導(dǎo)作用,而照片中的色彩、體積、位置和其他形狀等,都是為主導(dǎo)因素服務(wù)的。……構(gòu)圖中的對比,是指大與小、明與暗、近與遠(yuǎn)、主動與被動、平滑與粗糙、色彩的濃艷與輕淡等等的對比。要多利用這些相互對立的因素,通過它門使主體影響整個構(gòu)圖。例如,恰當(dāng)?shù)乩脤Ρ确▌t,照片就會具有強(qiáng)大的魅力。”?

    攝影家瓦爾特·德·格魯伊特對攝影構(gòu)圖作闡述。他認(rèn)為:“每一種構(gòu)圖都是以排列次序?yàn)榛A(chǔ)的,就像我們從哥士達(dá)心理學(xué)和信息學(xué)原理中所了解到的那樣,構(gòu)圖可以用多種方法獲得。它產(chǎn)生于相似事物的組合以及對相反事物的強(qiáng)調(diào)。排列次序并不是千篇一律的,形態(tài)和色彩的疏密和對比也會產(chǎn)生排列次序。排列次序是以一種美學(xué)上的均衡為基礎(chǔ)的,而均衡則從復(fù)雜、矛盾和動態(tài)之中造就和諧。”

    線條的引導(dǎo)作用,所有的線條匯聚到中心主體

    他說:“任何人,只要懂得把照片分成單個的構(gòu)圖成分,借以得出它在美學(xué)上的一致性和合理性來審查照片的具體效果,就都會成功地創(chuàng)作出好的作品。"?

    "要獲得令人滿意的照片構(gòu)圖,須經(jīng)常分析照片。” 他提出的分析照片構(gòu)圖的最重要標(biāo)準(zhǔn)是:?

    1.人物和環(huán)境的關(guān)系以及反差情況。 2.照片所傳遞的信息的價值以及類似事物。 3.照明和縱深。4.突出的線條和照片的畫幅。

    對于如何獲得較好的攝影構(gòu)圖,格魯伊特提出了以下重要建議:

    a.畫面所提供的信息不能造成視覺上的混亂。?

    b.人物和環(huán)境的關(guān)系要有助于傳達(dá)照片的意圖。?

    c.應(yīng)當(dāng)避免由于人物和環(huán)境之間的含糊關(guān)系而可能產(chǎn)生的錯覺。

    d.明與暗的關(guān)系或者彩色對比的關(guān)系是非常重要的。?

    e.除了人物和環(huán)境在形式上的關(guān)系之外,對人物和環(huán)境的心理上的權(quán)衡也是 十分重要的,因?yàn)槊總€視覺印象都立即作出喜歡或不喜歡的判斷。無偏好的估價意味著根本沒有反應(yīng)。?

    茉莉mm的“光繪”

    f.表現(xiàn)與我們熟悉的物體相類似的東西,使人容易辨認(rèn),從而能比較迅速地予以理解。因此,重復(fù)內(nèi)容是必要的。

    g.照片的復(fù)雜程度一定不能太低(感官刺激不夠),也不能太高(感官刺激過分)?

    h.每個人對每幅照片的美學(xué)評價總是不一樣的,而且這種評價是受感情支配的。它在很大程度上取決于觀眾的認(rèn)識,他的經(jīng)歷和他的敏感性。?

    i.形式主義和時髦風(fēng)尚是不能持久的。這種缺乏獨(dú)創(chuàng)性的缺點(diǎn),是不可能用技術(shù)補(bǔ)償?shù)摹?

    j.照明、透視、重疊和影紋的層次變化,有助于在二維空間的平面上體現(xiàn)出明顯的縱深感。

    k.不尋常的透視效果,有助于使照片生動活潑。?

    l.有意識地使用突出的方向線和選擇適合主體的畫幅,會加強(qiáng)照片的效果。

    更多名家名言和作者發(fā)表的個人看法,請訪問:

    posted @ 2006-09-27 13:49 ericli 閱讀(263) | 評論 (0)編輯 收藏

    2006年9月25日 #

    一些攝影方面的術(shù)語

    CCD:
    中文譯為"電子耦合組件"(charged coupled device),它就像傳統(tǒng)相機(jī)的底片一樣,是感應(yīng)光線的電路裝置,可以將它想象成一顆顆微小的感應(yīng)粒子,鋪滿在光學(xué)鏡頭后方,當(dāng)光線與圖像從鏡頭透過、投射到ccd表面時,ccd就會產(chǎn)生電流,將感應(yīng)到的內(nèi)容轉(zhuǎn)換成數(shù)碼資料儲存起來。ccd的尺寸其實(shí)是說感光器件的面積大小,ccd像素數(shù)目越多、單一像素尺寸越大,捕獲的光子越多,感光性能越好,信噪比越低,收集到的圖像就會越清晰。因此,盡管ccd數(shù)目并不是決定圖像品質(zhì)的唯一重點(diǎn),我們?nèi)匀豢梢园阉?dāng)成相機(jī)等級的重要判準(zhǔn)之一。

    CMOS:?
    互補(bǔ)性氧化金屬半導(dǎo)體CMOS(Complementary Metal-Oxide Semiconductor)和CCD一樣同為在數(shù)碼相機(jī)中可記錄光線變化的半導(dǎo)體。CMOS的制造技術(shù)和一般計算機(jī)芯片沒什么差別,主要是利用硅和鍺這兩種元素所做成的半導(dǎo)體,使其在CMOS上共存著帶N(帶–電) 和 P(帶+電)級的半導(dǎo)體,這兩個互補(bǔ)效應(yīng)所產(chǎn)生的電流即可被處理芯片紀(jì)錄和解讀成影像。同樣,CMOS的尺寸大小影響感光性能的效果,面積越大感光性能越好。CMOS的缺點(diǎn)就是太容易出現(xiàn)雜點(diǎn), 這主要是因?yàn)樵缙诘脑O(shè)計使CMOS在處理快速變化的影像時,由于電流變化過于頻繁而會產(chǎn)生過熱的現(xiàn)象。
    光學(xué)變焦倍數(shù):光學(xué)變焦是依靠光學(xué)鏡頭結(jié)構(gòu)來實(shí)現(xiàn)變焦,變焦方式與35mm相機(jī)差不多,就是通過攝像頭的鏡片移動來放大與縮小需要拍攝的景物,光學(xué)變焦倍數(shù)越大,能拍攝的景物就越遠(yuǎn)。如今的數(shù)碼相機(jī)的光學(xué)變焦倍數(shù)大多在2倍-5倍之間,也有一些碼相機(jī)擁有10倍的光學(xué)變焦效果。而家用攝像機(jī)的光學(xué)變焦倍數(shù)在10倍-25倍,能比較清楚地拍到70米外的東西。

    光圈:
    光圈英文名稱為Aperture,光圈是一個用來控制光線透過鏡頭,進(jìn)入機(jī)身內(nèi)感光面的光量的裝置,也是相機(jī)一個極其重要的指標(biāo)參數(shù),它通常是在鏡頭內(nèi)。它的大小決定著通過鏡頭進(jìn)入感光元件的光線的多少。表達(dá)光圈大小我們是用F值。光圈F值 = 鏡頭的焦距 / 鏡頭口徑的直徑從以上的公式可知要達(dá)到相同的光圈F值,長焦距鏡頭的口徑要比短焦距鏡頭的口徑大。

    ????我們平時所說的光圈值F2.8、F8、F16等是光圈“系數(shù)”,是相對光圈,并非光圈的物理孔徑,與光圈的物理孔徑及鏡頭到感光器件(膠片或CCD或CMOS)的距離有關(guān)。

    ????當(dāng)光圈物理孔徑不變時,鏡頭中心與感光器件距離愈遠(yuǎn),F(xiàn)數(shù)愈小,反之,鏡頭中心與感光器件距離愈近,通過光孔到達(dá)感光器件的光密度愈高,F(xiàn)數(shù)就愈大。完整的光圈值系列如下: F1, F1.4, F2, F2.8, F4, F5.6, F8, F11, F16, F22, F32, F44, F64。

    噪點(diǎn):
    噪點(diǎn)產(chǎn)生的原因:

    1、長時間曝光產(chǎn)生的圖像噪音

    ????這種現(xiàn)像主要大部分出現(xiàn)在拍攝夜景,在圖像的黑暗的夜空中,出線了一些孤立的亮點(diǎn)。可以說其原因是由于CCD無法處理較慢的快門速度所帶來的巨大的工作量,致使一些特定的像素失去控制而造成的。為了防止產(chǎn)生這種圖像噪音,部分?jǐn)?shù)碼相機(jī)中配備了被稱為"降噪"的功能。

    ????如果使用降噪功能,在記錄圖像之前就會利用數(shù)字處理方法來消除圖像噪音,因此在保存完畢以前就需要花費(fèi)一點(diǎn)額外的時間。

    2、用JPEG格式對圖像壓縮而產(chǎn)生的圖像噪音

    ????由于JPEG格式的圖像在縮小圖像尺寸后圖像仍顯得很自然,因此就可以利用特殊的方法來減小圖像數(shù)據(jù)。此時,它就會以上下左右8×8個像素為一個單位進(jìn)行處理。因此尤其是在8×8個像素邊緣的位置就會與下一個8×8個像素單位發(fā)生不自然的結(jié)合。

    ????由JPEG格式壓縮而產(chǎn)生的圖像噪音也被稱為馬賽克噪音(Block Noise),壓縮率越高,圖像噪音就越明顯。

    ????雖然把圖像縮小后這種噪音也會變得看不出來,但放大打印后,一進(jìn)行色彩補(bǔ)償就表現(xiàn)得非常明顯。這種圖像噪音可以通過利用盡可能高的畫質(zhì)或者利用JPEG格式以外的方法來記錄圖像而得以解決。

    3、模糊過濾造成的圖像噪音

    ????模糊過濾造成的圖像噪音和JPEG一樣,在對圖像進(jìn)行處理時造成的圖像噪音。有時是在數(shù)碼相機(jī)內(nèi)部處理過程中產(chǎn)生的,有時是利用圖像潤色軟件進(jìn)行處理時產(chǎn)生的。對于尺寸較小的圖像,為了使圖像顯得更清晰而強(qiáng)調(diào)其色彩邊緣時就會產(chǎn)生圖像噪音。

    ????所謂的清晰處理就是指數(shù)碼相機(jī)具有的強(qiáng)調(diào)圖像色彩邊緣的功能和圖像編輯軟件的“模糊過濾(Unsharp Mask)”功能。在不同款式的數(shù)碼相機(jī)中也有一些相機(jī)會對整個圖像進(jìn)行色彩邊緣的強(qiáng)調(diào)。而處理以后就會在原來的邊緣外側(cè)出現(xiàn)其他顏色的色線。

    ?? 如果將圖像尺寸縮小以后用于因特網(wǎng)的話,圖像不是總覺得會變得模糊不清嗎?此時如果利用“模糊過濾”功能對圖像進(jìn)行清晰處理,圖像看起來效果就會好一些。不過由于產(chǎn)生了圖像噪音,在進(jìn)行第二次或第三次處理時,這種圖像噪音就顯得很麻煩。切忌不要因?yàn)樘幚磉^度而使圖像顯得過于粗糙。?

    ????這里值得一題的是光圈F值愈小,在同一單位時間內(nèi)的進(jìn)光量便愈多,而且上一級的進(jìn)光量剛是下一級的一倍,例如光圈從F8調(diào)整到F5.6,進(jìn)光量便多一倍,我們也說光圈開大了一級。多數(shù)非專業(yè)數(shù)碼相機(jī)鏡頭的焦距短、物理口徑很小,F(xiàn)8時光圈的物理孔徑已經(jīng)很小了,繼續(xù)縮小就會發(fā)生衍射之類的光學(xué)現(xiàn)象,影響成像。所以一般非專業(yè)數(shù)碼相機(jī)的最小光圈都在F8至F11,而專業(yè)型數(shù)碼相機(jī)感光器件面積大,鏡頭距感光器件距離遠(yuǎn),光圈值可以很小。對于消費(fèi)型數(shù)碼相機(jī)而言,光圈F值常常介于F2.8 - F16。此外許多數(shù)碼相機(jī)在調(diào)整光圈時,可以做1/3級的調(diào)整。

    posted @ 2006-09-25 15:00 ericli 閱讀(265) | 評論 (0)編輯 收藏

    2006年9月13日 #

    SQL優(yōu)化原則


    ?SQL優(yōu)化原則
    ?
    1、使用索引來更快地遍歷表。
    缺省情況下建立的索引是非群集索引,但有時它并不是最佳的。在非群集索引下,數(shù)據(jù)在物理上隨機(jī)存放在數(shù)據(jù)頁上。合理的索引設(shè)計要建立在
    對各種查詢的分析和預(yù)測上。一般來說:
    a.有大量重復(fù)值、且經(jīng)常有范圍查詢( > ,< ,> =,< =)和order by、group by發(fā)生的列,可考
    慮建立群集索引;
    b.經(jīng)常同時存取多列,且每列都含有重復(fù)值可考慮建立組合索引;
    c.組合索引要盡量使關(guān)鍵查詢形成索引覆蓋,其前導(dǎo)列一定是使用最頻繁的列。索引雖有助于提高性能但不是索引越多越好,恰好相反過多的索引會導(dǎo)致系統(tǒng)低效。用戶在表中每加進(jìn)一個索引,維護(hù)索引集合就要做相應(yīng)的更新工作。
    2、在海量查詢時盡量少用格式轉(zhuǎn)換。
    3、ORDER BY和GROPU BY使用ORDER BY和GROUP BY短語,任何一種索引都有助于SELECT的性能提高。
    7、任何對列的操作都將導(dǎo)致表掃描,它包括數(shù)據(jù)庫函數(shù)、計算表達(dá)式等等,查詢時要盡可能將操作移至等號右邊。
    4、IN、OR子句常會使用工作表,使索引失效。如果不產(chǎn)生大量重復(fù)值,可以考慮把子句拆開。拆開的子句中應(yīng)該包含索引。

    Sql的優(yōu)化原則2:
    1、只要能滿足你的需求,應(yīng)盡可能使用更小的數(shù)據(jù)類型:例如使用MEDIUMINT代替INT
    2、盡量把所有的列設(shè)置為NOT NULL,如果你要保存NULL,手動去設(shè)置它,而不是把它設(shè)為默認(rèn)值。
    3、盡量少用VARCHAR、TEXT、BLOB類型
    4、如果你的數(shù)據(jù)只有你所知的少量的幾個。最好使用ENUM類型
    5、正如graymice所講的那樣,建立索引。
    以下是我做的一個實(shí)驗(yàn),可以發(fā)現(xiàn)索引能極大地提高查詢的效率:

    我有一個會員信息表users,里邊有37365條用戶記錄:

    在不加索引的時候進(jìn)行查詢:
    sql語句A:
    select * from users where username like ’%許%’;
    在Mysql-Front中的8次查詢時長為:1.40,0.54,0.54,0.54,0.53,0.55,0.54 共找到960條記錄

    sql語句B:
    select * from users where username like ’許%’;
    在Mysql-Front中的8次查詢時長為:0.53,0.53,0.53,0.54,0.53,0.53,0.54,0.54 共找到836條記錄

    sql語句C:
    select * from users where username like ’%許’;
    在Mysql-Front中的8次查詢時長為:0.51,0.51,0.52,0.52,0.51,0.51,0.52,0.51 共找到7條記錄

    為username列添加索引:
    create index usernameindex on users(username(6));

    再次查詢:
    sql語句A:
    select * from users where username like ’%許%’;
    在Mysql-Front中的8次查詢時長為:0.35,0.34,0.34,0.35,0.34,0.34,0.35,0.34 共找到960條記錄

    sql語句B:
    select * from users where username like ’許%’;
    在Mysql-Front中的8次查詢時長為:0.06,0.07,0.07,0.07,0.07,0.07,0.06,0.06 共找到836條記錄

    sql語句C:
    select * from users where username like ’%許’;
    在Mysql-Front中的8次查詢時長為:0.32,0.31,0.31,0.32,0.31,0.32,0.31,0.31 共找到7條記錄

    在實(shí)驗(yàn)過程中,我沒有另開任何程序,以上的數(shù)據(jù)說明在單表查詢中,建立索引的可以極大地提高查詢速度。
    另外要說的是如果建立了索引,對于like ’許%’類型的查詢,速度提升是最明顯的。因此,我們在寫sql語句的時候也盡量采用這種方式查詢。

    對于多表查詢我們的優(yōu)化原則是:

    盡量將索引建立在:left join on/right join on ... +條件,的條件語句中所涉及的字段上。

    多表查詢比單表查詢更能體現(xiàn)索引的優(yōu)勢。

    6、索引的建立原則:
    如果一列的中數(shù)據(jù)的前綴重復(fù)值很少,我們最好就只索引這個前綴。Mysql支持這種索引。我在上面用到的索引方法就是對username最左邊的6個字符進(jìn)行索引。索引越短,占用的

    磁盤空間越少,在檢索過程中花的時間也越少。這方法可以對最多左255個字符進(jìn)行索引。

    在很多場合,我們可以給建立多列數(shù)據(jù)建立索引。

    索引應(yīng)該建立在查詢條件中進(jìn)行比較的字段上,而不是建立在我們要找出來并且顯示的字段上

    7、限制索引的使用的避歸。
    7.1? IN、OR子句常會使用工作表,使索引失效。
    如果不產(chǎn)生大量重復(fù)值,可以考慮把子句拆開。拆開的子句中應(yīng)該包含索引。這句話怎么理解決,請舉個例子

    例子如下:
    如果在fields1和fields2上同時建立了索引,fields1為主索引
    以下sql會用到索引
    select * from tablename1 where fields1=’value1’ and fields2=’value2’
    以下sql不會用到索引
    select * from tablename1 where fields1=’value1’ or fields2=’value2’
    7.2 使用IS NULL 或IS NOT NULL
    ???????? 使用IS NULL 或IS NOT NULL同樣會限制索引的使用。因?yàn)镹ULL值并沒有被定義。在SQL語句中使用NULL會有很多的麻煩。因此建議開???? 發(fā)人員在建表時,把需要索引的列設(shè)成NOT NULL。如果被索引的列在某些行中存在NULL值,就不會使用這個索引(除非索引是一個位圖索引,關(guān)于位圖索引在稍后在詳細(xì)討論)。

    7.3 使用函數(shù)
    如果不使用基于函數(shù)的索引,那么在SQL語句的WHERE子句中對存在索引的列使用函數(shù)時,會使優(yōu)化器忽略掉這些索引。下面的查詢不會使用索引(只要它不是基于函數(shù)的索引)
    ?? select empno,ename,deptno
    ????????? from?? emp
    ????????? where? trunc(hiredate)='01-MAY-81';
    ????????? 把上面的語句改成下面的語句,這樣就可以通過索引進(jìn)行查找。
    ????????? select empno,ename,deptno
    ????????? from?? emp
    ????????? where? hiredate<(to_date('01-MAY-81')+0.9999);

    7.4 比較不匹配的數(shù)據(jù)類型
    比較不匹配的數(shù)據(jù)類型也是比較難于發(fā)現(xiàn)的性能問題之一。注意下面查詢的例子,account_number是一個VARCHAR2類型,在account_number字段上有索引。下面的語句將執(zhí)行全表掃描。
    ???????? select bank_name,address,city,state,zip
    ???????? from?? banks
    ???????? where? account_number = 990354;
    ???????? Oracle可以自動把where子句變成to_number(account_number)=990354,這樣就限制了索引的使用,改成下面的查詢就可以使用索引:
    ???????? select bank_name,address,city,state,zip
    ???????? from?? banks
    ???????? where? account_number ='990354';
    ???? 特別注意:不匹配的數(shù)據(jù)類型之間比較會讓Oracle自動限制索引的使用,即便對這個查詢執(zhí)行Explain Plan也不能讓您明白為什么做了一?????????????? 次“全表掃描”。

    補(bǔ)充:
    1.索引帶來查詢上的速度的大大提升,但索引也占用了額外的硬盤空間(當(dāng)然現(xiàn)在一般硬盤空間不成問題),而且往表中插入新記錄時索引也要隨著更新這也需要一定時間.
    有些表如果經(jīng)常insert,而較少select,就不用加索引了.不然每次寫入數(shù)據(jù)都要重新改寫索引,花費(fèi)時間;
    這個視實(shí)際情況而定,通常情況下索引是必需的.
    2.我在對查詢效率有懷疑的時候,一般是直接用Mysql的Explain來跟蹤查詢情況.
    你用Mysql-Front是通過時長來比較,我覺得如果從查詢時掃描字段的次數(shù)來比較更精確一些.

    ?

    ?

    posted @ 2006-09-13 20:25 ericli 閱讀(508) | 評論 (3)編輯 收藏

    取當(dāng)前日期 到 前3個月的sql記錄 怎么寫

    select * from t where 日期字段名字>DATEADD ( mm, -3, getdate())

    //t 是你的表名

    ?

    ?


    現(xiàn)在程序里得到當(dāng)前時間和3個月前的時間
    Date nowDate=new Date();
    Date oldDate=new Date();
    oldDate.setMonth(oldDate.getMonth()-3);

    select * from tab where 日期字段>oldDate and 日期字段<newDate

    posted @ 2006-09-13 20:24 ericli 閱讀(1940) | 評論 (0)編輯 收藏

    Struts初始化

    我在幾個月前曾經(jīng)發(fā)表過一個帖子,就是和大家一起學(xué)習(xí)struts源代碼。成為一名合格的程序員,閱讀大量的優(yōu)秀程序是必不可少的。只看書是不會讓你水平有很大提高的,要多看多寫。
    本來是打算等下面幾篇文章寫好后一起發(fā)布的,這樣大家可能才能看得明白些,但是根據(jù)我現(xiàn)在的狀況,估計還要一、兩個月。所以,為了防止在struts源代碼發(fā)生過大變化后我的文章就沒有太大價值了,所以就提前發(fā)表了,霍霍~~~
    我的email為:mariah_fan@hotmail.com,有什么不對的地方請大家指正:)
    struts作為J2EE的MVC框架已經(jīng)取得了很大的成功,下面將分幾篇文章說明struts源程序的結(jié)構(gòu)。
    第一篇? struts的初始化

    struts 的核心類是org.apache.struts.action.ActionServlet,這個類將會在struts第一次使用時,
    作為servlet初始化并存入tomcat容器。很顯然的,初始化將會調(diào)用init方法初始化相應(yīng)的數(shù)據(jù)。

    一、initInternal()方法:
    ??? 通過調(diào)用MessageResources.getMessageResources(internalName)方法生成一個
    ??? MessageResources類,getMessageResources是通過調(diào)用MessageResourcesFactory.
    ??? createResources(config)來實(shí)現(xiàn)的。至于MessageResourcesFactory是一個abstract類,任何
    ??? 繼承自它的類都要實(shí)現(xiàn)createResources方法,生成MessageResources對象。整個程序生成
    ??? MessageResourcesFactory使用了如下技巧:
    ??? MessageResourcesFactory.factoryClass = factoryClass;
    ??? MessageResourcesFactory.clazz = null;
    ??? 首先會通過factoryClass來定義一個類全名,然后通過ClassLoader.loadClass
    ??? (factoryClass)方法來生成這個類,并賦給clazz,然后通過newInstance來生成一個對象。
    ??? 在本程序中,生成MessageResources對象實(shí)際就是對如下屬性進(jìn)行了初始化:
    ??? this.factory = factory;("org.apache.struts.util.PropertyMessageResourcesFactory")
    ??? this.config = config;("org.apache.struts.action.ActionResources")
    ??? this.returnNull = returnNull;(true/false)

    ??? 對于MessageResources類的作用是根據(jù)不同的Locate來格式化相應(yīng)的string。或者把你需要改變
    ??? 的string存放到數(shù)組中,然后通過getMessage(Locale locale, String key, Object args[])
    ??? 方法來格式化。然后把格式好的string存放到HashMap里,這樣就可以為以后重用。這里的key是
    ??? 使用的locale.toString() + "." + key

    ??? 在PropertyMessageResources中的loadLocale方法用來讀取resource的初始化信息。首先它會
    ??? 通過一個HashMap檢測這個localKey相關(guān)的message是否已經(jīng)被初始化了,如果被初始化過就跳
    ??? 出,檢測的方法是locales.get(localeKey) != null。
    ??? 然后會讀取如下一個文件:
    ??? org/apache/struts/action/ActionResources_(localKey).properties,然后進(jìn)行如下操作:
    ??? Properties props = new Properties();
    ??? ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    ??? is = classLoader.getResourceAsStream(name);
    ??? props.load(is);
    ??? Iterator names = props.keySet().iterator();
    ??????? while (names.hasNext()) {
    ??????????? String key = (String) names.next();
    ??????????? if (log.isTraceEnabled()) {
    ??????????????? log.trace("? Saving message key '" + messageKey(localeKey, key));
    ??????????? }
    ??????????? messages.put(messageKey(localeKey, key), props.getProperty(key));
    ??? }

    ??? PropertyMessageResources 就是通過上面的loadLocale方法查找與Locale locale, String key
    ??? 相對對應(yīng)的Message.查找的次序如下locale.toString(),然后是
    ??? localeKey = localeKey.substring(0, underscore),然后是defaultLocale,然后是key。

    ??? 最后,resource類的結(jié)構(gòu)如下:
    ??? PropertyMessageResources extends MessageResources
    ??? PropertyMessageResourcesFactory extends MessageResourcesFactory

    二、initOther()方法:
    ??? 從servlet中獲取config和debug兩個參數(shù),然后初始化ConvertUtils對象。由于
    ??? ConvertUtils.deregister()的初始化,所有的Converter都是有初始值的,所以這里Struts自己
    ??? 把這些初始值設(shè)置為null,即轉(zhuǎn)換出錯的時候返回null,而不是初始值。使用ConvertUtils類的
    ??? 原因是由于從form傳輸過來的都是String類型的值,所以我們要把它們轉(zhuǎn)換成相應(yīng)的類型。

    ??? 提到幾個技巧:
    ??? *public boolean isIndexed() {
    ???????? if (type == null) {
    ???????????? return (false);
    ???????? //技巧一:判斷是否是一個Array類的方法
    ???????? } else if (type.isArray()) {
    ???????????? return (true);
    ???????? //技巧二:判斷type是否是List的一個父類或者父接口,或者與List為同一個類
    ???????? //要注意如果List是另一個primitive的TYPE類,那么type必須也是這個類才會
    ???????? //返回true,否則都是false。注意long.TYPE與Long.class是不同的
    ???????? } else if (List.class.isAssignableFrom(type)) {
    ???????????? return (true);
    ???????? } else {
    ??????????? return (false);
    ???????? }
    ???? }

    ??? *//componentType為Array類所存儲的元素的類別
    ???? Class componentType = indexedProperty.getClass().getComponentType();
    ???? //生成一個新的Array
    ???? Object newArray = Array.newInstance(componentType, (index + 1));
    ???? System.arraycopy(indexedProperty, 0, newArray, 0, length);
    ???? indexedProperty = newArray;
    ???? set(name, indexedProperty);
    ???? int newLength = Array.getLength(indexedProperty);
    ???? for (int i = length; i < newLength; i++) {
    ??????? Array.set(indexedProperty, i, createProperty(name+"["+i+"]", componentType));
    ???? }

    三、initServlet()方法:
    ??? 這個方法主要是通過digester類解析web.xml,對String servletMapping屬性進(jìn)行初始化。對于
    ??? digester說明如下:這是一個基于DOM的SAX實(shí)現(xiàn)的類,它是事件觸發(fā)的,根據(jù)xml文件的結(jié)構(gòu),
    ??? 每次讀到一個節(jié)點(diǎn)元素就會觸發(fā)一個事件。

    ??? InputStream input = getServletContext().getResourceAsStream("/WEB-INF/web.xml");
    ??? 這是一個比較少見的方法。首先通過this.servletName = getServletConfig().
    ??? getServletName()獲取servlet的名稱,然后根據(jù)
    ??? if (servletName.equals(this.servletName)) {
    ??????? this.servletMapping = urlPattern;
    ??? }
    ??? 來判斷當(dāng)前讀到的servlet名稱是否是我們運(yùn)行的servlet的名稱,如果是,就把url-pattern作為
    ??? 我們的servletMapping。

    四、getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this)
    ??? 把自己存儲到servletContext中,屬性名為Globals.ACTION_SERVLET_KEY。

    五、ModuleConfig moduleConfig = initModuleConfig("", config)
    ??? 這個方法使用由initOther()方法獲取的config值為要解析的xml路徑,用來初始化ModuleConfig。
    ??? 它首先采用與生成MessageResourcesFactory同樣的方法產(chǎn)生一個MessageResourcesFactory對象:
    ??? MessageResourcesFactory為一個抽象類,每一個繼承它的類都要實(shí)現(xiàn)
    ??? createModuleConfig(String prefix)方法。本程序使用的缺省的MessageResourcesFactory類為
    ??? org.apache.struts.config.impl.DefaultModuleConfigFactory,它
    ??? 的createModuleConfig(String prefix)方法會生成一個ModuleConfigImpl類。

    ??? ModuleConfigImpl類相當(dāng)于一個JavaBean,用來存放一個web模塊運(yùn)行時所需要的配置信息。當(dāng)
    ??? 然,一個web模塊可以擁有多個ModuleConfig,但是缺省的是prefix長度為0的ModuleConifg。它
    ??? 的每個屬性幾乎都是由HashMap組成的,它通過一個configured布爾值來描述當(dāng)前的ModuleConfig
    ??? 是否已經(jīng)被初始化完畢,在每存放一個屬性的時候都會監(jiān)測這個值。如果初始化完畢而還要改變
    ??? 里面的屬性值,則會報出IllegalStateException("Configuration is frozen")異常,現(xiàn)在對它
    ??? 的屬性簡單說明如下:
    ??? * protected HashMap actionConfigs:
    ????? 這個HashMap用來存儲ActionConfig對象。
    ??? * protected HashMap dataSources
    ????? 這個HashMap用來存儲DataSourceConfig對象。
    ??? * protected HashMap exceptions
    ????? 這個HashMap用來存儲ExceptionConfig對象。
    ??? * protected HashMap formBeans
    ????? 這個HashMap用來存儲FormBeanConfig對象。
    ??? * protected HashMap forwards
    ????? 這個HashMap用來存儲ForwardConfig對象。
    ??? * protected HashMap messageResources
    ????? 這個HashMap用來存儲MessageResourcesConfig對象。
    ??? * protected ArrayList plugIns
    ????? 這個HashMap用來存儲PlugInConfig對象。
    ??? * protected ControllerConfig controllerConfig
    ????? ControllerConfig類
    ??? * protected boolean configured
    ????? 標(biāo)志這個ModuleConfig是(true)否(false)配置完成。
    ??? * protected String prefix
    ????? 用來標(biāo)志和區(qū)分ModuleConfig類,同時在使用上面的config類初始化相應(yīng)的資源以后,也是通
    ????? 過這個prefix來區(qū)分所屬的不同的web模塊。
    ??? * protected String actionMappingClass = "org.apache.struts.action.ActionMapping"
    ????? ActionMapping類名,缺省為org.apache.struts.action.ActionMapping。

    ??? 初始化ModuleConfig的方法如下:
    ??? 首先是使用getServletConfig().getInitParameter("mapping")來獲取設(shè)定的ActionMapping類
    ??? 名,然后通過initConfigDigester()方法來生成一個digester。最后用","分隔config,對每一
    ??? 塊調(diào)用parseModuleConfigFile(prefix, paths, config, digester, path)方法解析。注意,這
    ??? 個方法實(shí)際上只有兩個參數(shù)是有意義的:path為我們要解析的xml文件,config用來初始化完成
    ??? 后保存到servletContext中。

    ??? 如果ModuleConfig中存放的FormBeanConfig為Dydamic類型,那么就調(diào)用
    ??? DynaActionFormClass.createDynaActionFormClass(FormBeanConfig)初始化
    ??? DynaActionFormClass,并存放到DynaActionFormClass.dynaClasses 的 static HashMap中。這
    ??? 里的key為FormBeanConfig.getName() + moduleConfig.getPrefix()。
    ???
    ??? 如果當(dāng)前的ModuleConfig為缺省的ModuleConfig,那么將會調(diào)用如下幾個方法:
    ??? defaultControllerConfig(config)
    ??? defaultMessageResourcesConfig(config)
    ??? defaultFormBeansConfig(config)
    ??? defaultForwardsConfig(config)
    ??? defaultMappingsConfig(config)
    ??? 在struts1.1以后,這個特例將會被廢棄:

    ??? defaultControllerConfig(config)為ControllerConfig通過getInitParameter(s)方法初始化如
    ??? 下幾個屬性:bufferSize,content,locale(true/false),maxFileSize,nocache(true/false)
    ??? ,multipartClass,tempDir。

    ??? defaultMessageResourcesConfig(config)為MessageResourcesConfig通過getInitParameter(s)
    ??? 方法初始化如下幾個屬性:application,factory,null(true/false)。

    ??? 其它的幾個方法就是獲取不同的對象,然后把它們相應(yīng)的存儲到servlet中。關(guān)心如下:
    ??? ActionFormBeans=>FormBeanConfig,ActionForwards=>ForwardConfig,
    ??? ActionMappings=>ActionConfig。

    六、initModuleMessageResources(ModuleConfig config)
    ??? 通過存儲在ModuleConfig中的MessageResourcesConfig對象,逐個初始化MessageResource,
    ??? 然后再把初始化好的MessageResources存放到ServletContext中,attributeName為
    ??? MessageResourcesConfig.getKey() + ModuleConfig.getPrefix()。

    七、initModuleDataSources(ModuleConfig config)
    ??? 通過存儲在ModuleConfig中的DataSourceConfig對象,逐個初始化DataSource。然后對于每一個
    ??? DateSource通過BeanUtils.populate(ds, dscs[i].getProperties())方法初始化其屬性。再把初
    ??? 始化好的DateSource存放到ServletContext中,attributeName為
    ??? DataSourceConfig.getKey() + ModuleConfig.getPrefix()。同時也存放到名位dataSources的
    ??? FastHashMap中,key為DataSourceConfig.getKey()。

    ??? 這里還會根據(jù)生成的DateSource對象是否是GenericDataSource類型,如果是則調(diào)用
    ??? GenericDataSource.open()方法。GenericDataSource是一個非常簡單的數(shù)據(jù)庫連接池,它的
    ??? open()方法用來初始化連接池,生成最小數(shù)目的GenericConnection,這里的open()方法根據(jù)
    ??? String driver變量是否為null來判斷是否已經(jīng)被初始化過。需要仔細(xì)說明的是getConnection()
    ??? 方法,它首先從連接池中取出GenericConnection對象,然后檢查其是否是可鏈接的,如果是就
    ??? 返回,否則繼續(xù)取出,同時activeCount-1。如果沒有取到,則會檢查當(dāng)前可使用的
    ??? GenericConnection是否達(dá)到最大值(activeCount < maxCount),如果沒有,調(diào)用
    ??? createConnection()方法聲成一個新的GenericConnection,然后檢查其是否是可鏈接,如果可以
    ??? 則返回。returnConnection(GenericConnection conn)方法則是通過把GenericConnection放回到
    ??? 連接池,然后activeCount-1。

    ??? 這個方法中使用到了ServletContextWriter類,DateSource的log信息就通過這個類寫入。對這個
    ??? 類說明如下:
    ??? 它繼承自PrintWriter,而PrintWriter又繼承自Writer。Writer類所作的事情就是在同步的情況下
    ??? 調(diào)用abstract方法:abstract public void write(char cbuf[], int off, int len),這個方法
    ??? 將會根據(jù)調(diào)用者的需要由調(diào)用者實(shí)現(xiàn)。
    ??? PrintWriter則首先通過ensureOpen()方法檢驗(yàn)這個類中是否有寫入的對象(Writer類或其子類),
    ??? 如果有則根據(jù)不同的情況調(diào)用這個寫入對象的write方法(out.write(....))。這個類的print(...)
    ??? 方法就是據(jù)不同的情況調(diào)用相應(yīng)的write(...)方法。而println(...)與之的區(qū)別就是每次多寫入一
    ??? 個換行字符串。還有一個區(qū)別是println(...)會根據(jù)是否需要autoflush進(jìn)行flush,而write(...)
    ??? 方法不會。
    ??? ServletContextWriter類的作用是把字符寫入ServletContext中。ServletContextWriter類方法中
    ??? 真正實(shí)現(xiàn)了write方法:
    ??? public void write(char c) {
    ??????? if (c == '\n')
    ??????????? flush();
    ??????? else if (c != '\r')
    ??????????? buffer.append(c);
    ??? }
    ??? public void flush() {
    ??????? if (buffer.length() > 0) {
    ??????????? context.log(buffer.toString());
    ??????????? buffer.setLength(0);
    ??????? }
    ??? }

    八、initModulePlugIns(moduleConfig)
    ??? 通過存儲在ModuleConfig中的PlugInConfig對象,逐個初始化PlugIn對象,存放到一個數(shù)組中,
    ??? 然后再把這個數(shù)組存放到ServletContext中,attributeName為
    ??? Globals.PLUG_INS_KEY + ModuleConfig.getPrefix()。

    ??? 對每一個生成的PlugIn對象通過
    ??? BeanUtils.populate(plugIns[i], plugInConfigs[i].getProperties())方法初始化其屬性。然后
    ??? 再把PlugInConfig對象存放到由其生成的PlugIn對象中。

    ??? 最后,通過plugIns[i].init(this, (ModuleConfig) config)初始化這個plugIn對象。

    九、初始化結(jié)束
    ??? 完成了這個初始化以后,會調(diào)用ModuleConfig.freeze()令這個ModuleConfig變得不可改變。然后
    ??? 會遍歷ServletConfig中的initParameterNames,如果有以"config/"開頭的,則通過這個parameter
    ??? 的值繼續(xù)初始化其它的ModuleConfig,且這個ModuleConfig的prefix為"config/"后的字符串。
    ???
    ??? 同樣調(diào)用如下方法:
    ??? initModuleMessageResources(moduleConfig);
    ??? initModuleDataSources(moduleConfig);
    ??? initModulePlugIns(moduleConfig);
    ??? moduleConfig.freeze();

    ??? 最后調(diào)用destroyConfigDigester()釋放內(nèi)存。

    posted @ 2006-09-13 20:24 ericli 閱讀(367) | 評論 (0)編輯 收藏

    Struts1.1源碼解析

    Struts1.1b3部分源代碼分析.
    作者:???? 文章來源:
    訪問次數(shù): 次??? 加入時間:2006-05-12
    ?
    Struts1.1部分源代碼分析
    一:說明
    本文針對Struts1.1b3做分析,主要希望通過對源代碼的分析闡述Struts1.1的工作方式。
    本文不適合初學(xué)者參考,適合具有一定基于Struts開發(fā)的程序員參考。
    下面的描述;里面將會對ActionServlet,RequestProcessor,ModuleConfig等幾個類做一些
    說明。以注釋源代碼的方式,說明取工作流程。
    特別申明:Struts1.1代碼版權(quán)屬于Apache遵循The Apache Software License, Version 1.1.
    本文版權(quán)屬于孤魂一笑個人所有,任何個人或組織希望轉(zhuǎn)載,請與我聯(lián)系。并獲得我的授權(quán)
    方可轉(zhuǎn)載。

    二:ActionServlet分析
    我們先來看一下使用Struts的配置文件。


    action
    org.apache.struts.action.ActionServlet


    definitions-config
    /WEB-INF/tiles-defs.xml,/WEB-INF/tiles-tests-defs.xml,/WEB-INF/tiles-tutorial-defs.xml,
    /WEB-INF/tiles-examples-defs.xml


    definitions-debug
    0


    definitions-parser-details
    0


    definitions-parser-validate
    true

    ?

    config
    /WEB-INF/struts-config.xml

    ?

    config/examples
    /WEB-INF/struts-examples-config.xml

    ?

    config/test
    /WEB-INF/struts-tests-config.xml

    ?

    config/tutorial
    /WEB-INF/struts-tutorial-config.xml


    validate
    true


    debug
    2


    detail
    2

    ?

    application
    org.apache.struts.webapp.tiles.dev1-1.ApplicationResources


    2

    ?


    action
    *.do

    ?

    接下來我們來看一下ActionServlet的具體使用
    javax.servlet.http.HttpServlet
    |
    |-->org.apache.struts.action.ActionServlet
    所以本質(zhì)上ActionServlet是一個普通的servlet,負(fù)責(zé)處理.do為后綴的Http請求.
    servlet在執(zhí)行doGet(),doPost(),之前先調(diào)用init(),
    以下我們先分析一下init()方法
    /**
    * Initialize this servlet. Most of the processing has been factored into
    * support methods so that you can override particular functionality at a
    * fairly granular level.

    * servlet初始化操作,注意初始化順序
    * @exception ServletException if we cannot configure ourselves correctly
    */
    public void init() throws ServletException {
    //注意初始化的順序
    //Initialize our internal MessageResources bundle
    initInternal();
    //Initialize other global characteristics of the controller servlet
    //處理一些全局變量的設(shè)置如:debug,detail等
    initOther();
    //Initialize the servlet mapping under which our controller servlet
    //is being accessed. This will be used in the &html:form>
    //tag to generate correct destination URLs for form submissions
    //主要是注冊DTD文件以及解析web.xml關(guān)于ActionServlet的配置。如后綴名等.
    // Configure the processing rules that we need
    // digester.addCallMethod("web-app/servlet-mapping",
    // "addServletMapping", 2);
    // digester.addCallParam("web-app/servlet-mapping/servlet-name", 0);
    // digester.addCallParam("web-app/servlet-mapping/url-pattern", 1);
    //initServlet()的上面一段將把Struts默認(rèn)的后綴名從web.xml中解析得到
    //也就是web.xml中的如下配置:
    //
    //action
    //*.do
    //默認(rèn)以.do結(jié)尾的請求都將由Struts來處理,你可以自己修改
    //
    initServlet();

    // Initialize modules as needed
    //在Attribute中保存類實(shí)例
    getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
    //根據(jù)配置文件生成ModuleConfig,這是很重要的一步.下面會專門分析
    //在tiles的配置中先解析注釋為"Mark 0"的一個配置文件:/WEB-INF/struts-config.xml
    //使用initModuleConfig方法解析XML文件.
    //參數(shù)為prefix:"",paths:"/WEB-INF/struts-config.xml"
    ModuleConfig moduleConfig = initModuleConfig("", config);
    //初始化Message
    initModuleMessageResources(moduleConfig);
    //初始化JDBC DataSource
    initModuleDataSources(moduleConfig);
    //初始化PlunIn
    initModulePlugIns(moduleConfig);

    moduleConfig.freeze();
    //在Struts1.1以后可以使用多個配置文件,在解析完默認(rèn)的配置文件也就是上面提到的
    //注釋為"Mark 0"的一個配置文件:/WEB-INF/struts-config.xml后解析其他的配置文件
    Enumeration names = getServletConfig().getInitParameterNames();
    //依次解析注釋為"Mark 1"、"Mark 2"、"Mark 3"對應(yīng)配置文件
    while (names.hasMoreElements()) {
    //每一個配置文件的文件名
    String name = (String) names.nextElement();
    if (!name.startsWith("config/")) {
    continue;
    }
    //
    String prefix = name.substring(6);
    moduleConfig = initModuleConfig
    (prefix, getServletConfig().getInitParameter(name));

    initModuleMessageResources(moduleConfig);
    initModuleDataSources(moduleConfig);
    initModulePlugIns(moduleConfig);
    moduleConfig.freeze();
    }
    destroyConfigDigester();

    }
    /**
    * 此方法使用Digester解析XML,關(guān)于使用Digester的介紹參看我的另外一篇文章
    *
    Initialize the application configuration information for the
    * specified module.


    *
    * @param prefix Module prefix for this module
    * @param paths Comma-separated list of context-relative resource path(s)
    * for this modules's configuration resource(s)
    *
    * @exception ServletException if initialization cannot be performed
    * @since Struts 1.1
    */
    protected ModuleConfig initModuleConfig
    (String prefix, String paths) throws ServletException {

    if (log.isDebugEnabled()) {
    log.debug("Initializing module path '" + prefix +
    "' configuration from '" + paths + "'");
    }

    // Parse the configuration for this module
    ModuleConfig config = null;
    InputStream input = null;
    String mapping = null;
    try {
    //工廠方法創(chuàng)建ModuleConfig標(biāo)記為:prefix
    ModuleConfigFactory factoryObject =
    ModuleConfigFactory.createFactory();
    config = factoryObject.createModuleConfig(prefix);

    // Support for module-wide ActionMapping type override
    mapping = getServletConfig().getInitParameter("mapping");
    if (mapping != null) {
    config.setActionMappingClass(mapping);
    }

    // Configure the Digester instance we will use
    //得到解析XML的digester
    Digester digester = initConfigDigester();

    // Process each specified resource path
    while (paths.length() > 0) {
    //開始解析指定路徑文件名的文件
    digester.push(config);
    String path = null;
    //文件是否為多個并且使用","分割
    int comma = paths.indexOf(',');
    //存在多個配置文件
    if (comma >= 0) {
    //先解析第一個
    path = paths.substring(0, comma).trim();
    //paths存放剩余的文件名下次再處理
    paths = paths.substring(comma + 1);
    } else {
    //當(dāng)前只存在一個
    path = paths.trim();
    //沒有剩余,下次循環(huán)根據(jù)上面一句將會在唯一的循環(huán)退出點(diǎn)"point break"
    //退出循環(huán)
    paths = "";
    }
    //全部解析完成跳出循環(huán)
    //point break
    if (path.length() < 1) {
    break;
    }
    //根據(jù)文件名取文件
    URL url = getServletContext().getResource(path);
    InputSource is = new InputSource(url.toExternalForm());
    input = getServletContext().getResourceAsStream(path);
    is.setByteStream(input);
    digester.parse(is);
    //全局變量的形式把解析生成的ModuleConfig實(shí)例保存起來
    //如"Mark 1"處標(biāo)記的"config/examples",
    //key為:"org.apache.struts.action.MODULEexamples"
    //Globals.MODULE_KEY值為:org.apache.struts.action.MODULE
    getServletContext().setAttribute
    (Globals.MODULE_KEY + prefix, config);
    input.close();
    }

    } catch (Throwable t) {
    log.error(internal.getMessage("configParse", paths), t);
    throw new UnavailableException
    (internal.getMessage("configParse", paths));
    } finally {
    if (input != null) {
    try {
    input.close();
    } catch (IOException e) {
    ;
    }
    }
    }

    // Force creation and registration of DynaActionFormClass instances
    // for all dynamic form beans we wil be using
    //根據(jù)ModuleConfig實(shí)例得到配置的FormBean的配置
    //注意:因?yàn)樵赟truts整個運(yùn)行當(dāng)中FormBean的實(shí)例要在Action的實(shí)例創(chuàng)建之前先創(chuàng)建
    //因?yàn)锳ction執(zhí)行perform(1.1以前),execute(1.1)需要使用到FormBean
    FormBeanConfig fbs[] = config.findFormBeanConfigs();
    for (int i = 0; i < fbs.length; i++) {
    if (fbs[i].getDynamic()) {
    DynaActionFormClass.createDynaActionFormClass(fbs[i]);
    }
    }

    // Special handling for the default module (for
    // backwards compatibility only, will be removed later)
    //下面是生成一些實(shí)例
    if (prefix.length() < 1) {
    defaultControllerConfig(config);
    defaultMessageResourcesConfig(config);
    defaultFormBeansConfig(config);
    defaultForwardsConfig(config);
    defaultMappingsConfig(config);
    }

    // Return the completed configuration object
    //config.freeze(); // Now done after plugins init
    return (config);

    }

    到此初始化工作基本結(jié)束,下面將處理具體的Http請求。在Servlet協(xié)議中所有的post方法將調(diào)用
    以下方法來處理
    public void doPost(HttpServletRequest request,
    HttpServletResponse response)
    throws IOException, ServletException {}
    get方法也調(diào)用類似的方法來處理

    在Struts中post,get方法都調(diào)用同一個方法
    process(request, response);來處理具體的請求
    如下:
    /**
    * 對每一個提交過來的Action進(jìn)行處理
    * Perform the standard request processing for this request, and create
    * the corresponding response.
    *
    * @param request The servlet request we are processing
    * @param response The servlet response we are creating
    *
    * @exception IOException if an input/output error occurs
    * @exception ServletException if a servlet exception is thrown
    */
    protected void process(HttpServletRequest request,
    HttpServletResponse response)
    throws IOException, ServletException {
    //設(shè)置或刪除Attribute
    RequestUtils.selectModule(request, getServletContext());
    //具體的處理交給RequestProcessor去處理HttpRequest,HttpResponse
    //這是一個很典型的設(shè)計模式
    //下面我們將詳細(xì)來分析RequestProcessor,很容易理解Struts的運(yùn)行方式
    getRequestProcessor(getModuleConfig(request)).process(request, response);
    }

    三:RequestProcessor分析
    通過前面的分析我們知道Struts中對HttpRequest,HttpResponse的處理都交給RequestProcessor
    的process()方法來處理。下面我們來看看process方法
    /**
    *
    Process an HttpServletRequest and create the
    * corresponding HttpServletResponse.


    *
    * @param request The servlet request we are processing
    * @param response The servlet response we are creating
    *
    * @exception IOException if an input/output error occurs
    * @exception ServletException if a processing exception occurs
    */
    public void process(HttpServletRequest request,
    HttpServletResponse response)
    throws IOException, ServletException {

    // Wrap multipart requests with a special wrapper
    //如果是upload,返回一個MultipartRequestWrapper()
    request = processMultipart(request);

    // Identify the path component we will use to select a mapping
    //對request進(jìn)行分析得到提交過來的Form Action
    String path = processPath(request, response);
    if (path == null) {
    return;
    }
    if (log.isInfoEnabled()) {
    log.info("Processing a '" + request.getMethod() +
    "' for path '" + path + "'");
    }

    // Select a Locale for the current user if requested
    //本地化處理
    processLocale(request, response);

    // Set the content type and no-caching headers if requested
    processContent(request, response);
    //設(shè)置Cache不保存
    processNoCache(request, response);

    // General purpose preprocessing hook
    if (!processPreprocess(request, response)) {
    return;
    }

    // Identify the mapping for this request
    //得到path以后,根據(jù)配置文件(struts-config.xml)的相關(guān)配置來得到一個
    //ActionMapping的實(shí)例
    //ActionMapping繼承ActionConfig
    //仔細(xì)看一下ActionMapping的代碼就能發(fā)現(xiàn):
    //下面的一段將解析影射一個ActionMapping的實(shí)例
    //在ActionServlet在初始化的時候?qū)嶋H上已經(jīng)把所有的ActionMapping的實(shí)例
    //都已經(jīng)創(chuàng)建好了。processMapping方法實(shí)際上是從Attribute中去得到已經(jīng)
    //保存好的ActionMapping的實(shí)例,可以理解為在Tomcat啟動的時候已經(jīng)
    //把所有的ActionMapping保存在Attribute里面。所以在Tomcat啟動的時候
    //比較慢,如果Struts-config.xml有問題啟動就會出錯。
    /***

    type="org.apache.struts.webapp.tiles.test.TestActionTileAction">

    ?

    **/
    //****注意得到創(chuàng)建實(shí)例的順序
    //ActionMapping實(shí)例已經(jīng)創(chuàng)建好了,現(xiàn)在從Atribute中取到
    ActionMapping mapping = processMapping(request, response, path);
    if (mapping == null) {
    return;
    }

    // Check for any role required to perform this action
    if (!processRoles(request, response, mapping)) {
    return;
    }

    // Process any ActionForm bean related to this request
    //根據(jù)mapping得到ActionForm的實(shí)例。
    //同名ActionForm在系統(tǒng)中只會創(chuàng)建一次。
    ActionForm form = processActionForm(request, response, mapping);
    //壓棧
    processPopulate(request, response, form, mapping);
    //處理校驗(yàn),調(diào)用ActionForm的validate方法
    //假如出錯將會返回到前一頁面
    //也就是說在Action還沒有創(chuàng)建之前就將做校驗(yàn)
    if (!processValidate(request, response, form, mapping)) {
    return;
    }

    // Process a forward or include specified by this mapping
    if (!processForward(request, response, mapping)) {
    return;
    }
    if (!processInclude(request, response, mapping)) {
    return;
    }

    // Create or acquire the Action instance to process this request
    //在得到ActionMapping、ActionForm的實(shí)例后接下來得到Action實(shí)例
    //實(shí)例如果已經(jīng)創(chuàng)建從Map里面去取如果沒有創(chuàng)建一個并保存在Map里面
    //對保存Action實(shí)例的Map 實(shí)現(xiàn)線程同步
    Action action = processActionCreate(request, response, mapping);
    if (action == null) {
    return;
    }

    // Call the Action instance itself
    //在ActionMapping、ActionForm、Action實(shí)例創(chuàng)建好以后
    //調(diào)用Action的execute()方法得到一個ActionForward
    //因?yàn)樗械目蓤?zhí)行Action都必須有override Action的execute()/perform()方法
    ActionForward forward =
    processActionPerform(request, response,
    action, form, mapping);

    // Process the returned ActionForward instance
    //Action已經(jīng)正常執(zhí)行,執(zhí)行結(jié)束后將返回到另外一個頁面
    processActionForward(request, response, forward);

    }

    仔細(xì)閱讀上面的代碼,要特別注意ActionMapping、ActionForm、Action的實(shí)例是依次創(chuàng)建的。
    創(chuàng)建完以后才去執(zhí)行Action的execute()方法。為什么要依次創(chuàng)建ActionMapping、ActionForm
    、Action??????


    四:ModuleConfig分析
    現(xiàn)在我們很有必要了解一下ModuleConfig這個類,因?yàn)樘嗟胤接玫搅恕?br />實(shí)際上ModuleConfig是一個接口有一個實(shí)現(xiàn)。org.apache.struts.config.impl.ModuleConfigImpl
    具體實(shí)現(xiàn)我就沒有不要去分析了。我們來看看這個接口。

    package org.apache.struts.config;

    /**
    *
    The collection of static configuration information that describes a
    * Struts-based module. Multiple modules are identified by
    * a prefix at the beginning of the context
    * relative portion of the request URI. If no module prefix can be
    * matched, the default configuration (with a prefix equal to a zero-length
    * string) is selected, which is elegantly backwards compatible with the
    * previous Struts behavior that only supported one module.


    *
    * @author Rob Leland
    * @version $Revision: 1.2 $ $Date: 2002/12/22 05:31:14 $
    * @since Struts 1.1
    */
    public interface ModuleConfig {
    /**
    * Has this module been completely configured yet. Once this flag
    * has been set, any attempt to modify the configuration will return an
    * IllegalStateException.
    */
    boolean getConfigured();

    /**
    * The controller configuration object for this module.
    */
    ControllerConfig getControllerConfig();
    /**
    * The controller configuration object for this module.
    * @param cc The controller configuration object for this module.
    */

    void setControllerConfig(ControllerConfig cc);

    /**
    * The prefix of the context-relative portion of the request URI, used to
    * select this configuration versus others supported by the controller
    * servlet. A configuration with a prefix of a zero-length String is the
    * default configuration for this web module.
    */
    String getPrefix();

    /**
    * The prefix of the context-relative portion of the request URI, used to
    * select this configuration versus others supported by the controller
    * servlet. A configuration with a prefix of a zero-length String is the
    * default configuration for this web module.
    */
    public void setPrefix(String prefix);
    /**
    * The default class name to be used when creating action mapping
    * instances.
    */
    String getActionMappingClass();
    /**
    * The default class name to be used when creating action mapping
    * instances.
    * @param actionMappingClass default class name to be used when creating action mapping
    * instances.
    */

    void setActionMappingClass(String actionMappingClass);

    /**
    * Add a new ActionConfig instance to the set associated
    * with this module.
    *
    * @param config The new configuration instance to be added
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void addActionConfig(ActionConfig config);

    /**
    * Add a new DataSourceConfig instance to the set associated
    * with this module.
    *
    * @param config The new configuration instance to be added
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void addDataSourceConfig(DataSourceConfig config);

    /**
    * Add a new ExceptionConfig instance to the set associated
    * with this module.
    *
    * @param config The new configuration instance to be added
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void addExceptionConfig(ExceptionConfig config);

    /**
    * Add a new FormBeanConfig instance to the set associated
    * with this module.
    *
    * @param config The new configuration instance to be added
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void addFormBeanConfig(FormBeanConfig config);

    /**
    * Add a new ForwardConfig instance to the set of global
    * forwards associated with this module.
    *
    * @param config The new configuration instance to be added
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void addForwardConfig(ForwardConfig config);

    /**
    * Add a new MessageResourcesConfig instance to the set
    * associated with this module.
    *
    * @param config The new configuration instance to be added
    *
    * @exception IllegalStateException if this module configuration
    * has been frozen
    */
    void addMessageResourcesConfig(MessageResourcesConfig config);

    /**
    * Add a newly configured {@link org.apache.struts.config.PlugInConfig} instance to the set of
    * plug-in Actions for this module.
    *
    * @param plugInConfig The new configuration instance to be added
    */
    void addPlugInConfig(PlugInConfig plugInConfig);

    /**
    * Return the action configuration for the specified path, if any;
    * otherwise return null.
    *
    * @param path Path of the action configuration to return
    */
    ActionConfig findActionConfig(String path);

    /**
    * Return the action configurations for this module. If there are
    * none, a zero-length array is returned.
    */
    ActionConfig[] findActionConfigs();

    /**
    * Return the data source configuration for the specified key, if any;
    * otherwise return null.
    *
    * @param key Key of the data source configuration to return
    */
    DataSourceConfig findDataSourceConfig(String key);

    /**
    * Return the data source configurations for this module. If there
    * are none, a zero-length array is returned.
    */
    DataSourceConfig[] findDataSourceConfigs();

    /**
    * Return the exception configuration for the specified type, if any;
    * otherwise return null.
    *
    * @param type Exception class name to find a configuration for
    */
    ExceptionConfig findExceptionConfig(String type);

    /**
    * Return the exception configurations for this module. If there
    * are none, a zero-length array is returned.
    */
    ExceptionConfig[] findExceptionConfigs();

    /**
    * Return the form bean configuration for the specified key, if any;
    * otherwise return null.
    *
    * @param name Name of the form bean configuration to return
    */
    FormBeanConfig findFormBeanConfig(String name);

    /**
    * Return the form bean configurations for this module. If there
    * are none, a zero-length array is returned.
    */
    FormBeanConfig[] findFormBeanConfigs();

    /**
    * Return the forward configuration for the specified key, if any;
    * otherwise return null.
    *
    * @param name Name of the forward configuration to return
    */
    ForwardConfig findForwardConfig(String name);

    /**
    * Return the form bean configurations for this module. If there
    * are none, a zero-length array is returned.
    */
    ForwardConfig[] findForwardConfigs();

    /**
    * Return the message resources configuration for the specified key,
    * if any; otherwise return null.
    *
    * @param key Key of the data source configuration to return
    */
    MessageResourcesConfig findMessageResourcesConfig(String key);

    /**
    * Return the message resources configurations for this module.
    * If there are none, a zero-length array is returned.
    */
    MessageResourcesConfig[] findMessageResourcesConfigs();

    /**
    * Return the configured plug-in actions for this module. If there
    * are none, a zero-length array is returned.
    */
    PlugInConfig[] findPlugInConfigs();

    /**
    * Freeze the configuration of this module. After this method
    * returns, any attempt to modify the configuration will return
    * an IllegalStateException.
    */
    void freeze();

    /**
    * Remove the specified action configuration instance.
    *
    * @param config ActionConfig instance to be removed
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void removeActionConfig(ActionConfig config);

    /**
    * Remove the specified exception configuration instance.
    *
    * @param config ActionConfig instance to be removed
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void removeExceptionConfig(ExceptionConfig config);

    /**
    * Remove the specified data source configuration instance.
    *
    * @param config DataSourceConfig instance to be removed
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void removeDataSourceConfig(DataSourceConfig config);

    /**
    * Remove the specified form bean configuration instance.
    *
    * @param config FormBeanConfig instance to be removed
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void removeFormBeanConfig(FormBeanConfig config);

    /**
    * Remove the specified forward configuration instance.
    *
    * @param config ForwardConfig instance to be removed
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void removeForwardConfig(ForwardConfig config);

    /**
    * Remove the specified message resources configuration instance.
    *
    * @param config MessageResourcesConfig instance to be removed
    *
    * @exception java.lang.IllegalStateException if this module configuration
    * has been frozen
    */
    void removeMessageResourcesConfig(MessageResourcesConfig config);
    }


    上面的注釋已經(jīng)非常清晰了。我就不去浪費(fèi)大家的時間了,再想仔細(xì)看就去看他的實(shí)現(xiàn)。
    其實(shí)主要是對HashMap()的處理。

    五:ActionMapping分析
    最后我們實(shí)現(xiàn)很有必要看一下ActionMapping,因?yàn)槟闳绻肭宄牧私釹truts-config.xml
    這個配置文件的作用,你應(yīng)該要知道ActionMapping
    前面已經(jīng)說過ActionMapping繼承ActionConfig
    以下就是ActionMapping加的四個方法。
    /**
    *
    Find and return the ExceptionConfig instance defining
    * how exceptions of the specified type should be handled. This is
    * performed by checking local and then global configurations for the
    * specified exception's class, and then looking up the superclass chain
    * (again checking local and then global configurations). If no handler
    * configuration can be found, return null.


    *
    * @param type Exception class for which to find a handler
    * @since Struts 1.1
    */
    public ExceptionConfig findException(Class type) {

    }


    /**
    *
    Find and return the ForwardConfig instance defining
    * how forwarding to the specified logical name should be handled. This is
    * performed by checking local and then global configurations for the
    * specified forwarding configuration. If no forwarding configuration
    * can be found, return null.


    *
    * @param name Logical name of the forwarding instance to be returned
    */
    public ActionForward findForward(String name) {

    }


    /**
    *
    Return the logical names of all locally defined forwards for this
    * mapping. If there are no such forwards, a zero-length array
    * is returned.
    */
    public String[] findForwards() {
    }


    /**
    *

    Create (if necessary) and return an {@link ActionForward} that
    * corresponds to the input property of this Action.
    *
    * @since Struts 1.1b2
    */
    public ActionForward getInputForward() {

    }

    還是看以下他的基類ActionConfig吧
    public class ActionConfig implements Serializable {

    /**
    * Has configuration of this component been completed?
    */
    protected boolean configured = false;

    /**
    * The set of exception handling configurations for this
    * action, if any, keyed by the type property.
    */
    protected HashMap exceptions = new HashMap();

    /**
    * The set of local forward configurations for this action, if any,
    * keyed by the name property.
    */
    protected HashMap forwards = new HashMap();

    /**
    * The module configuration with which we are associated.
    */
    protected ModuleConfig moduleConfig = null;

    /**
    * The request-scope or session-scope attribute name under which our
    * form bean is accessed, if it is different from the form bean's
    * specified name.
    */
    protected String attribute = null;

    /**
    * Context-relative path of the web application resource that will process
    * this request via RequestDispatcher.forward(), instead of instantiating
    * and calling the Action class specified by "type".
    * Exactly one of forward, include, or
    * type must be specified.
    */
    protected String forward = null;

    /**
    * Context-relative path of the web application resource that will process
    * this request via RequestDispatcher.include(), instead of instantiating
    * and calling the Action class specified by "type".
    * Exactly one of forward, include, or
    * type must be specified.
    */
    protected String include = null;

    /**
    * Context-relative path of the input form to which control should be
    * returned if a validation error is encountered. Required if "name"
    * is specified and the input bean returns validation errors.
    */
    protected String input = null;

    /**
    * Fully qualified Java class name of the
    * MultipartRequestHandler implementation class used to
    * process multi-part request data for this Action.
    */
    protected String multipartClass = null;

    /**
    * Name of the form bean, if any, associated with this Action.
    */
    protected String name = null;

    /**
    * General purpose configuration parameter that can be used to pass
    * extra iunformation to the Action instance selected by this Action.
    * Struts does not itself use this value in any way.
    */
    protected String parameter = null;

    /**
    * Context-relative path of the submitted request, starting with a
    * slash ("/") character, and omitting any filename extension if
    * extension mapping is being used.
    */
    protected String path = null;

    /**
    * Prefix used to match request parameter names to form ben property
    * names, if any.
    */
    protected String prefix = null;

    /**
    * Comma-delimited list of security role names allowed to request
    * this Action.
    */
    protected String roles = null;

    /**
    * Identifier of the scope ("request" or "session") within which
    * our form bean is accessed, if any.
    */
    protected String scope = "session";

    /**
    * Suffix used to match request parameter names to form bean property
    * names, if any.
    */
    protected String suffix = null;

    /**
    * Fully qualified Java class name of the Action class
    * to be used to process requests for this mapping if the
    * forward and include properties are not set.
    * Exactly one of forward, include, or
    * type must be specified.
    */
    protected String type = null;

    /**
    * Should the validate() method of the form bean associated
    * with this action be called?
    */
    protected boolean validate = true;
    }

    其實(shí)ActionConfig是一個很典型的ValueObject.所以其他的get/set方法我就不寫出來了。
    看這個代碼一定要和struts-config.xml一起來看,根據(jù)struts-config.xml去找找
    每一段配置文件最終要生成一個ActionConfig,他們之間的對應(yīng)關(guān)系。
    如果你想擴(kuò)展Struts,ActionMapping估計你一定要修改。還有ActionServlet你也要修改。

    六:結(jié)束語
    分析了一些代碼下面做一些概述。先來整體的了解一下Struts的工作流程.
    在實(shí)現(xiàn)一個基于Struts的運(yùn)用之前我們首先是做環(huán)境設(shè)置,Struts正常工作需要至少兩個
    配置文件web.xml,struts-config.xml.
    web.xml告訴App Server所有以.do結(jié)尾的請求最終提交給ActionServlet去處理。
    2就規(guī)定ActionServlet是在App Server啟動的時候
    創(chuàng)建的并且一直存在。
    ActionServlet在創(chuàng)建的時候會做如下的工作:
    保存一些后面需要使用的實(shí)例在Attribute(內(nèi)存)里面。
    根據(jù)web.xml的配置解析struts-config.xml文件。
    根據(jù)struts-config.xml的配置生成ActionMapping實(shí)例并且保存。

    ActionServlet在生命周期就一直等待Http 請求
    每一個.do結(jié)尾的Http 請求都由ActionServlet先截獲然后根據(jù)請求路徑得到具體調(diào)用那
    一個Action去處理,在這之前生成、處理ActionForm。具體知道那一個Action去處理請求
    后調(diào)用Action的execute()/perform()處理完成,返回。


    ?

    posted @ 2006-09-13 20:23 ericli 閱讀(1391) | 評論 (0)編輯 收藏

    Toad中出現(xiàn)問題

    ?toad連接出現(xiàn)問題:
    可能是一些環(huán)境變量被修改了,比如昨天我碰到的問題
    d:\oracle\ora92\BIN 被修改了,在path 里面將其配置好,就可以了
    正常的配置信息如下:
    ?(Oracle Root)
    ? ORACLE_HOME = d:\oracle\ora92
    ? ORACLE_SID =
    ? NLS_LANG = NA
    ? SQLPATH =
    ? d:\oracle\ora92\BIN is in system PATH
    ? d:\oracle\ora92\BIN does exist
    ? Client dll found oci.dll
    ? oci.dll version: 9.2.0.1.0??
    ? (Oracle Root) is valid
    HOME0
    ? ORACLE_HOME_NAME = OraHome92
    ? ORACLE_HOME = d:\oracle\ora92
    ? ORACLE_SID = NHOALG
    ? NLS_LANG = SIMPLIFIED CHINESE_CHINA.ZHS16GBK
    ? SQLPATH = d:\oracle\ora92\dbs
    ? d:\oracle\ora92\BIN is in system PATH
    ? d:\oracle\ora92\BIN does exist
    ? Client dll found oci.dll
    ? oci.dll version: 9.2.0.1.0
    ? HOME0 is valid
    $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
    同事遇到問題,toad安裝好一次后,就打不開了
    是版本的問題,換了一個版本就好了
    7.6--8.0
    ?

    posted @ 2006-09-13 20:21 ericli 閱讀(672) | 評論 (0)編輯 收藏

    Eclipse ShortCut

    ★ Eclipse 3.0 RC2 熱鍵表 (中英對照版,Default) ★

    Author:sungo
    Date:2004/06/16 (三)


    ◎閱讀說明:冒號 ( : )後的藍(lán)色標(biāo)註熱鍵為Eclipse預(yù)設(shè)的標(biāo)準(zhǔn)熱鍵,空
    白即表示Eclipse並未對該項目設(shè)熱鍵;紅色標(biāo)註選項表示常用或重要熱
    鍵;淡粉紅色標(biāo)註選項,表示可以啟動該熱鍵的範(fàn)圍。

    ◎熱鍵修改處:
    Window->Preference->Workbench->Keys

    ◎FAQ,如果沒設(shè)熱鍵的功能要如何啟動?
    方法一.自己增設(shè)熱鍵。
    方法二.熱鍵設(shè)定裡的選項,其實(shí)功能表大部分都有,可以由功能表中直接點(diǎn)選。

    ◎給所有在看這篇文章的朋友:
    T55555為了JavaWorld週年慶把DG2拿出來了,為了效法他的精神,所以我決定把
    我的第一次也貢獻(xiàn)出來,加入JavaWorld這半年來我第一次打這麼長的文章...XD
    。本來打算3.0 Release出來後再整理熱鍵表,但3.0 RC系列架構(gòu)已經(jīng)趨於平穩(wěn),
    Release出來也不會有多大的變動,所以就先整理了。熱鍵表所列的功能,只要您
    全部實(shí)際操作過一遍,將會為您在操作Eclipse上,帶來莫大的助益。

    -------------------------------------------------------------------------------------------------------------

    Compare - 比較
    Copy All from Left to Right (由左向右複製全部)
    Copy All from Right to Left (由右向左複製全部)
    Copy from Left to Right (由左向右複製)
    Copy from Right to Left (由右向左複製)
    Select Next Change (選取下一個變更)
    Select Previous Change (選取上一個變更)

    CVS - Concurrent Versions System (版本控制系統(tǒng))
    Checkout from CVS (由CVS檢查)

    Edit - 編輯
    Add Bookmark (新增書籤)
    Add Task (新增作業(yè))
    Collapse (程式碼折疊) : Ctrl+鍵盤右方數(shù)字區(qū)的'-' <Editing Text>
    Content Assist (內(nèi)容輔助 - Code Templetes啟動): Alt+/ 或 Ctrl+Space <In Dialogs and Windows>
    Context Information (內(nèi)容資訊) : Alt+? 或 ALT+Shift+?或 Ctrl+Shift+Space <In Windows>
    Copy (複製選取文字到OS剪貼簿) : Ctrl+C <In Dialogs and Windows>
    Custom Encoding (自訂編碼)
    Cut (剪下選取文字並加至OS剪貼簿) : Ctrl+X <In Dialogs and Windows>
    Default Encoding (使用預(yù)設(shè)編碼)
    Delete (刪除選取的文字) : Delete <In Windows>
    Expand (程式碼展開) : Ctrl+鍵盤右方數(shù)字區(qū)的'+' <Editing Text>
    Expand All (程式碼全部展開) : Ctrl+鍵盤右方數(shù)字區(qū)的'*' <Editing Text>
    Find and Replace (尋找並取代文字) : Ctrl+F <In Windows>
    Find Next (尋找下一個項目) : Ctrl+K <Editing Text>
    Find Previous (尋找上一個項目) : Ctrl+Shift+K <Editing Text>
    Incremental Find (漸進(jìn)式尋找) : Ctrl+J <Editing Text>
    Incremental Find Reverse (逆向漸進(jìn)式尋找) : Ctrl+Shift+J <Editing Text>
    ISO-8859-1 Encoding (將編碼變更為 ISO-8859-1)
    Paste (從OS剪貼簿貼上文字) : Ctrl+V <In Dialogs and Windows>
    Quick Diff Toggle (QuickDiff 開啟/關(guān)閉) : Ctrl+Shift+Q <Editing Text>
    Quick Fix (快速套件修正) : Ctrl+1 <Editing Java Source>
    Redo (重做上一次作業(yè)) : Ctrl+Y <In Windows>
    Restore Last Selection (恢復(fù)最後選取) : Alt+Shift+方向鍵'↓' <Editing Java Source>
    Revert to Saved (回復(fù)至已儲存)
    Select All (選擇全部文字) : Ctrl+A <In Dialogs and Windows>
    Select Enclosing Element : (選取含括的元素) Alt+Shift+方向鍵'↑' <Editing Java Source>
    Select Next Element (選取下一個元素) : Alt+Shift+方向鍵'→' <Editing Java Source>
    Select Previous Element (選取上一個元素) : Alt+Shift+方向鍵'←' <Editing Java Source>
    Shift Left (將該行文字往左移動一個縮排)
    Shift Right (將該行文字往右移動一個縮排)
    Show Tooltip Description (在游標(biāo)位置顯示元素的工具提示說明) : F2 <Editing Java Source>
    System Encoding (將編碼變更為系統(tǒng)編碼)
    Toggle Folding (程式碼折疊、展開功能 開啟/關(guān)閉) : Ctrl+鍵盤右方數(shù)字區(qū)的'/' <Editing Text>
    Toggle Insert Model (Smart Insert模式 開啟/關(guān)閉) : Ctrl+Shift+Insert <Editing Text>
    Undo (復(fù)原前次作業(yè)) : Ctrl+Z <In Windows>
    US ASCII Encoding (將編碼變更為 ASCII)
    UTF-16BE Encoding (將編碼變更為 UTF-16BE)
    UTF-16 Encoding (將編碼變更為 UTF-16)
    UTF-16LE Encoding (將編碼變更為 UTF-16LE)
    UTF-8 Encoding (將編碼變更為 UTF-8)

    File - 檔案
    Close (關(guān)閉檔案) : Ctrl+W 或 Ctrl+F4 <In Windows>
    Close All (關(guān)閉全部檔案) : Ctrl+Shift+W 或 Ctrl+Shift+F4 <In Windows>
    Exit (關(guān)閉螢?zāi)蛔钌蠈右暣? : Alt+F4 <In Dialogs and Windows>?? 0
    (註:3.0RC2並沒預(yù)設(shè)這組熱鍵,但仍然可以使用。)

    Export (開啟匯出功能表)
    Import (開啟匯入功能表)
    Move (移動檔案)
    New (開啟檔案建立精靈Wizard) : Ctrl+N <In Windows>
    New menu (顯示File->New選單) : ALT+Shift+N <In Windows>
    Open External File (開啟外部檔案)
    Open Workspace (開啟Workspace設(shè)定視窗)
    Print (列印檔案) : Ctrl+P <In Windows>
    Properties (org.eclipse.ui.file.properties) (顯示檔案內(nèi)容) : Alt+Enter <In Windows>
    Refresh (重新整理) : F5 <In Windows>
    Rename (重新命名) : F2 <In Windows>
    Revert (回復(fù)至已儲存)
    Save (儲存檔案) : Ctrl+S <In Windows>
    Save All (儲存全部檔案) : Ctrl+Shift+S <In Windows>
    Save As (另存新檔)

    Help - 說明
    About (開啟關(guān)於對話框)
    Help Contents (開啟Eclipse說明文件)
    Tips and Tricks (開啟要訣和技巧說明頁面)
    Weclome (開啟歡迎使用頁面)

    Navigate - 導(dǎo)覽
    Back (向後導(dǎo)覽)
    Backward History (在編輯器導(dǎo)覽歷程中向後移動) : Alt+方向鍵'←' <In Windows>
    Forward (向前導(dǎo)覽)
    Forward History (在編輯器導(dǎo)覽歷程中向前移動) : Alt+方向鍵'→' <In Windows>
    Go Into (進(jìn)入選取的目錄內(nèi))
    Go to Line (移至某一行文字) : Ctrl+L <Editing Text>
    Go to Matching Bracket (將游標(biāo)移至對稱的方括弧) : Ctrl+Shift+P <Editing Java Source>
    Go to Next Member (移至下一個Member) : Ctrl+Shift+方向鍵'↓' <Editing Java Source>
    Go to Package (移至套件,用於Package Explorer)
    Go to Previous Member (移至上一個Member) : Ctrl+Shift+方向鍵'↑' <Editing Java Source>
    Go to Resource (移至資源)
    Go to Type (移至類別,用於Package Explorer)
    Last Edit Loaction (移至前次編輯位置) : Ctrl+Q <In Windows>
    Next (移至下一個標(biāo)示元素) : Ctrl+. <In Windows>
    (註:元素類型可由Toolbar的Next Annotation小倒三角圖示設(shè)定。)

    Open Call Hierarchy (開啟Call Hierarchy視窗) : Ctrl+Alt+H <In Windows>
    Open Declaration (瀏覽所選取的Java元素) : F3 <In Windows> (註:效果等於Ctrl+滑鼠左鍵點(diǎn)選。)
    Open External Javadoc (開啟外部Javadoc) : Shift+F2 <In Windows>
    Open Resource (開啟資源選取對話方塊) : Ctrl+Shift+R <In Windows>
    Open Structure (顯示所選元素的結(jié)構(gòu)) : Ctrl+F3 <Editing Java Source>
    Open Super Implementation (開啟super類型中的實(shí)作)
    Open Type (開啟類別) : Ctrl+Shift+T <In Windows>
    Open Type Hierarchy (開啟類別階層顯示視窗) : F4 <In Windows>
    Open Type in Hierarchy (在類別階層的視圖中開啟類別) : Ctrl+Shift+H <In Windows>
    Previous (移至上一個標(biāo)示元素) : Ctrl+, <In Windows>
    (註:元素類型可由Toolbar的Previous Annotation小倒三角圖示設(shè)定。)

    Quick Hierarchy (以浮動方式將類別階層視窗顯示在編輯器上) : Ctrl+T <Editing Java Source>
    Quick Outline (以浮動方式將概要視窗顯示在編輯器上) : Ctrl+O <Editing Java Source>
    Show In menu (顯示當(dāng)前Show In功能表可用的選項) : Alt+Shift+W <In Windows>
    Show in Package Explorer (在套件瀏覽器中顯示所選元素)
    Up (導(dǎo)覽上一層)

    Project - 專案
    Build All (建置所有專案) : Ctrl+B <In Windows>
    Build Clean (清除專案)
    Build Project (建置專案)
    Close Project (關(guān)閉專案)
    Generate Javadoc (產(chǎn)生Javadoc)
    Open Project (開啟專案)
    Properties (org.eclipse.ui.project.properties) (開啟專案屬性設(shè)定視窗)
    Rebuild All (重新建置所有專案)
    Rebuild Project (重新建置專案)
    Repeat Working Set Build (重複建置所設(shè)定的專案) (註:Build Automatically 關(guān)閉時才可使用。)

    Refactor - Java (重構(gòu) - Java)
    Change Method Signature (變更方法簽章) : Alt+Shift+C <In Windows>
    Convert Anonymous Class to Nested (將匿名類別轉(zhuǎn)換成巢狀類別)
    Convert Local Variable to Field (將區(qū)域變數(shù)轉(zhuǎn)換成欄位) : Alt+Shift+F <Editing Java Source>
    Encapsulate Field (封裝欄位:為欄位建立getting和setting方法,並只用這些方法來存取欄位)
    Extract Constant (擷取成常數(shù):將數(shù)字?jǐn)X取至新的Static欄位,並使用新的Static欄位)

    註:<-START->

    如下段程式碼經(jīng)由Extract Constant重構(gòu)數(shù)字10後...
    12345
    ?public class Test {
    ??? public static void main(String[] args) {
    ??????? int x = 10;
    ??? }
    }

    ?
    會變成下列程式碼:(常數(shù)欄位名稱,在重構(gòu)時可以自由設(shè)定。)123456
    ?public class Test {
    ??? public static final int TEN = 10;
    ??? public static void main(String[] args) {
    ??????? int x = TEN;
    ??? }
    }

    ?
    註:<-END->

    Extract Interface (擷取成介面:將原類別內(nèi)的方法擷取至新介面中,原類別將實(shí)作該介面)
    (註:新介面會存成一個新的*.java檔。若是在interface中執(zhí)行此功能,舊介面則會繼承新介面。)
    Extract Local Variable (擷取成區(qū)域變數(shù):將數(shù)字?jǐn)X取為新的區(qū)域變數(shù)) : Alt+Shift+L <In Windows>
    Extract Method (擷取成方法:將選取的表示式擷取成一個新方法) : Alt+Shift+M <In Windows>
    Generalize Type (將reference的類別型態(tài)更改可以取代的Superclass)
    Inline (列入常數(shù)、區(qū)域變數(shù)或方法) : Alt+Shift+I <In Windows>
    Introduce Factory (採用代理:利用方法來取得建構(gòu)子)

    註:<-START->

    如下段程式碼經(jīng)由Introduce Factory重構(gòu)Test建構(gòu)子後...
    123456789
    ?public class Test {
    ??? private int number;
    ??? Test(int x) {
    ??????? number = x;
    ??? }
    ??? public static void main(String[] args) {
    ??????? System.out.println(new Test(5).number);
    ??? }
    }

    ?
    會變成下列程式碼:123456789101112
    ?public class Test {
    ??? private int number;
    ??? public Test(int x) {
    ??????? number = x;
    ??? }
    ??? public static void main(String[] args) {
    ??????? System.out.println(createTest(5).number);
    ??? }
    ??? public static Test createTest(int x) {
    ??????? return new Test(x);
    ??? }
    }

    ?
    註:<-END->

    Introduce Parameter (採用參數(shù):將區(qū)域變數(shù)改成參數(shù)方式傳遞)

    註:<-START->

    如下段程式碼經(jīng)由Introduce Parameter重構(gòu)數(shù)字5後...
    12345
    ?public class Test {
    ??? public static void main(String[] args) {
    ??????? int x = 5;
    ??? }
    }

    ?
    會變成下列程式碼:12345
    ?public class Test {
    ??? public static void main(String[] args, int five) {
    ??????? int x = five;
    ??? }
    }

    ?
    註:<-END->

    Move Member Type to New File (將類別成員移至一個新檔)
    Move - Refactoring (移動 - 重構(gòu):將所選取的元素移至新位置) : Alt+Shift+V <In Windows>
    Pull Up (將類別成員<欄位與方法>上推到類別的父類別中)
    Push Down (將類別成員(欄位與方法)下推到類別的子類別中)
    Redo - Refactoring (重做 - 重構(gòu):重做前次的重構(gòu)) : Alt+Shift+Y <In Windows>
    Refactor Quick Menu (在編輯區(qū)顯示重構(gòu)的快速功能表) : Alt+Shift+T <In Windows>
    Rename - Refactoring (更名 - 重構(gòu):將所選取的元素重新命名,類別名稱、區(qū)域變數(shù)名稱等...) :
    Alt+Shift+R <In Windows>
    Undo - Refactoring (復(fù)原 - 重構(gòu):復(fù)原前次的重構(gòu)) : Alt+Shift+Z <In Windows>
    Use Supertype Where Possible (啟動「適當(dāng)時使用父類別」重構(gòu)對話框。)

    ◎補(bǔ)充命名規(guī)則:(重構(gòu)時不照此規(guī)則命名時,Eclipse將會警示,
    雖然可以不管警示,但這是個好風(fēng)格。)

    1.介面(interface)名稱:開頭大寫。
    2.區(qū)域變數(shù)(Local Variable)名稱:開頭小寫 。
    3.常數(shù)欄位(public static final int...)名稱:全部大寫。

    Run/Debug - 執(zhí)行/除錯
    Add Class Load Breakpoint (新增一個類別載入中斷點(diǎn)))
    Add Java Exception Breakpoint (新增一個Java異常狀況中斷點(diǎn))
    Debug... (開啟除錯啟動配置對話框)
    Debug Last Launched (開啟最近一次啟動作業(yè)的除錯模式) : F11 <In Windows>
    Display (org.eclipse.jdt.debug.ui.commands.Display) (顯示) : Ctrl+Shift+D <In Windows>
    (註:當(dāng)執(zhí)行緒暫停時,此指令會使用「顯示」檢視畫面,顯示在該執(zhí)行緒之堆疊框或變數(shù)的環(huán)境定義下
    ,評估所選表示式的結(jié)果。)

    Execute (執(zhí)行:開啟執(zhí)行啟動配置對話框) : Ctrl+U <In Windows>
    Inspect (觀察): Ctrl+Shift+I <In Windows>
    (註:當(dāng)執(zhí)行緒暫停時,此指令會使用「表示式」檢視畫面,顯示在該執(zhí)行緒之堆疊框或變數(shù)的環(huán)境定義
    下,視察所選表示式或變數(shù)的結(jié)果。)

    Profile Last Launched (最近一次作業(yè)的概況)
    Resume (繼續(xù)執(zhí)行緒的執(zhí)行) : F8 <Debugging>
    Run Last Launched (在執(zhí)行模式下迅速執(zhí)行最近一次的啟動作業(yè)): Ctrl+F11 <In Windows>
    Run Last Launched External Tool (執(zhí)行前一次啟動的外部工具)
    Run to Line (執(zhí)行至指定行,可在沒有設(shè)定中斷點(diǎn)之處暫停執(zhí)行) : Ctrl+R <Debugging>
    Skip All Breakpoints (在不清除中斷點(diǎn)的情況下,執(zhí)行時跳過所有的中斷點(diǎn))
    Step Into (進(jìn)入副程序) : F5 <Debugging>
    Step Into Selection (進(jìn)入目前所選的陳述式進(jìn)行副程序除錯) : Ctrl+F5 <Debugging>
    Step Over (跳過副程序) : F6 <Debugging>
    Step Return (跳出副程序): F7 <Debugging>
    Suspend (暫停執(zhí)行緒)
    Terminate (終止執(zhí)行緒)
    Toggle Breakpoint (新增/移除,中斷點(diǎn)) : Ctrl+Shift+B <In Windows>
    Toggle Method Breakpoint (新增/移除,方法中斷點(diǎn))
    Toggle Step Filters (以過濾條件逐步除錯) : Shift+F5 <In Windows>
    Toggle Watchpoint (新增/移除,欄位的監(jiān)視點(diǎn))

    Search - 搜索
    Declaration in Hierarchy (在它的階層中搜尋所選元素的宣告)
    Declaration in Project (在專案中搜尋所選元素的宣告)
    Declaration in Working Set (在工作集中搜尋所選元素的宣告)
    Declaration in Workspace (在工作區(qū)中搜尋所選元素的宣告) : Ctrl+G <In Windows>
    Exception Occurrences (搜索例外事件)
    File Search (開啟搜尋對話框的檔案搜尋頁面)
    Implementors in Project (在專案中搜尋所選介面的實(shí)作者)
    Implementors in Working Set (在工作集中搜尋所選介面的實(shí)作者)
    Implementors in Workspace (在工作區(qū)中搜尋所選介面的實(shí)作者)
    Occurrences in File (在它的宣告檔案中搜尋所選元素的所有出現(xiàn)處) : Ctrl+Shift+U <In Windows>
    Open Search Dialog (開啟搜尋對話框) : Ctrl+H <In Windows>
    Read Access in Hierarchy (在它的階層中搜尋所選元素的讀取參考)
    Read Access in Project (在專案中搜尋所選元素的讀取參考)
    Read Access in Working Set (在工作集中搜尋所選元素的讀取參考)
    Read Access in Workspace (在工作區(qū)中搜尋所選元素的讀取參考)
    References in Hierarchy (在它的階層中搜尋所選元素的參考)
    References in Project (在專案中搜尋所選元素的參考)
    References in Working Set (在工作集中搜尋所選元素的參考)
    References in Workspace (在工作區(qū)中搜尋所選元素的參考) : Ctrl+Shift+G <In Windows>
    Referring Tests (查詢測試)
    Write Access in Hierarchy (在它的階層中搜尋所選元素的寫入?yún)⒖?
    Write Access in Project (在專案中搜尋所選元素的寫入?yún)⒖?
    Write Access in Working Set (在工作集中搜尋所選元素的寫入?yún)⒖?
    Write Access in Workspace (在工作區(qū)中搜尋所選元素的寫入?yún)⒖?

    Source - 程式碼
    Add Block Comment (將選取的字行以多行註解/**/包起來) : Ctrl+Shift+/ <Editing Java Source>
    Add Constructors from Superclass (從父類別增加一個建構(gòu)子)
    Add Import (為目前所選的類別參考建立一項匯入宣告) : Ctrl+Shift+M <Editing Java Source>
    Add Javadoc Comment (新增Javadoc註解) : Alt+Shift+J <In Windows>
    Comment (註解)
    Externalize Strings (開啟「外部化字串」精靈)
    Find Strings to Externalize (尋找要外部化的字串)
    Format (程式碼自動排版) : Ctrl+Shift+F <Editing Java Source>
    Format Element (格式化元素)
    Generate Constructor using Fields (使用欄位來產(chǎn)生建構(gòu)子)

    註:<-START->

    如下段程式碼,選取欄位名稱money並經(jīng)由Generate Constructor using Fields指令後...
    12345
    ?public class Test {
    ??? int money;
    ??? public static void main(String[] args) {
    ??? }
    }

    ?
    會變成下列程式碼:12345678
    ?public class Test {
    ??? int money;
    ??? public Test(int money) {
    ??????? this.money = money;
    ??? }
    ??? public static void main(String[] args) {
    ??? }
    }

    ?
    註:<-END->

    Generate Delegate Methods (開啟「產(chǎn)生委派方法」對話框,可新增類型欄位的委派方法)
    Generate Getters and Setters (開啟「產(chǎn)生Getter與Setter」對話框,可以為欄位自動
    建立Getter和Setter方法)
    Indent Line (單行縮排,其會遵照Formatter設(shè)定的格式) : Ctrl+I <Editing Java Source>
    Mark Occurrences (標(biāo)註事件): Alt+Shift+O <Editing Java Source>
    Organize Imports (組織匯入) : Ctrl+Shift+O <In Windows>
    (註:這是個很方便的功能,簡易說明一下使用時機(jī):假設(shè)我們在程式中打,JFrame src;而並未
    import任何swing類別,此時Eclipse便會出現(xiàn)錯誤警示,用紅底線將JFrame標(biāo)起來,此時只要按
    下Ctrl+Shift+O,Eclipse便會自動將:import javax.swing.JFrame;加到程式碼中了。)

    Override/Implement Methods (開啟「覆寫/實(shí)作方法」對話框,可覆寫或?qū)嵶鳜F(xiàn)行類別中的方法)
    Remove Block Comment (移除多行註解/**/) : Ctrl+Shift+\ <Editing Java Source>
    Remove Occurrence Annotations (移除事件書籤): Alt+Shift+U <Editing Java Source>
    Sort Members (排序成員)
    Source Quick Menu (在編輯區(qū)顯示Source的快速功能表) : Alt+Shift+S <In Windows>
    Surround with try/catch Block (以try/catch區(qū)塊包覆所選文字)
    Toggle Comment (加上單行註解/取消單行註解) : Ctrl+/ 或 Ctrl+7 或 Ctrl+Shift+C
    <Editing Java Source>
    Uncomment (取消註解)

    ◎補(bǔ)充,Source 隱藏?zé)徭I:
    1.Shift Right (向右移位,增加目前所選字行的內(nèi)縮層次) : Tab <Editing Java Source>
    2.Shift Left (向左移位,減少目前所選字行的內(nèi)縮層次) : Shift+Tab <Editing Java Source>

    Team - 團(tuán)隊
    Synchronize (同步化)

    Text Editing - 文字編輯
    Claer Mark (清除標(biāo)記)
    Copy Lines (將選取的文字,複製成新行) : Ctrl+Alt+方向鍵'↓' <Editing Text>
    Cut Line (剪下單行文字)
    Cut to Beginning of Line (剪下文字,範(fàn)圍為選取處至單行開頭)
    Cut to End of Line (剪下文字,範(fàn)圍為選取處至單行尾端)
    Delete Line (刪除單行文字) : Ctrl+D <Editing Text>
    Delete Next (刪除下一行)
    Delete Next Word (刪除下一個字組) : Ctrl+Delete <Editing Text>
    Delete Previous (刪除前一行)
    Delete Previous Word (刪除前一個字組) : Ctrl+Backspace <Editing Text>
    Delete to Beginning of Line (刪除文字,範(fàn)圍為選取處至單行開頭)
    Delete to End of Line (刪除文字,範(fàn)圍為選取處至單行尾端)
    Duplicate Lines (將選取的文字,複製成新行) : Ctrl+Alt+方向鍵'↑' <Editing Text>
    Insert Line Above Current Line (在游標(biāo)處的該行上方插入新行) : Ctrl+Shift+Enter <Editing Text>
    Insert Line Below Current Line (在游標(biāo)處的該行下方插入新行) : Shift+Enter <Editing Text>
    Line Down (游標(biāo)往下移一行)
    Line End (游標(biāo)移至該行尾端)
    Line Start (游標(biāo)移至該行開頭)
    Line Up (游標(biāo)往上移一行)
    Move Lines Down (將該行文字往下移動) : Alt+方向鍵'↓' <Editing Text>
    Move Lines Up (將該行文字往上移動) : Alt+方向鍵'↑' <Editing Text>
    Next Column (游標(biāo)移至下一列)
    Next Word (游標(biāo)移至下一個字組) : Ctrl+方向鍵'→' <Editing Text>
    Page Down (移至下一頁)
    Page Up (移至上一頁)
    Previous Column (游標(biāo)移至上一列)
    Previous Word (游標(biāo)移至上一個字組) : Ctrl+方向鍵'←' <Editing Text>
    Scroll Line Down (向下捲動) : Ctrl+方向鍵'↓' <Editing Text>
    Scroll Line Up (向上捲動) : Ctrl+方向鍵'↑' <Editing Text>
    Select Line Down (選取下一行)
    Select Line End (選取至文字尾端)
    Select Line Start (選取至文字開頭)
    Select Line Up (選取上一行)
    Select Next Column (選取下一列)
    Select Next Word (選取下一個字組): Ctrl+Shift+方向鍵'→' <Editing Text>
    Select Page Down (選取下一頁)
    Select Page Up (選取上一頁)
    Select Previous Column (選取上一列)
    Select Previous Word (選取前一個字組) : Ctrl+Shift+方向鍵'←' <Editing Text>
    Select Text End (選取至文字編輯器尾端)
    Select Text Start (選取至文字編輯器開頭)
    Select Window End (選取至視窗尾端)
    Select Window Start (選取至視窗開頭)
    Set Mark (設(shè)定標(biāo)記)
    Swap Mark (交換標(biāo)記)
    Text End (游標(biāo)移至文字編輯器最底端)
    Text Start (游標(biāo)移至文字編輯器最頂端)
    Toggle Overwrite (覆寫/插入 模式選擇) : Insert <Editing Text>
    To Lower Case (將選取的英文字轉(zhuǎn)為小寫) : Ctrl+Shift+Y <Editing Text>
    To Upper Case (將選取的英文字轉(zhuǎn)為大寫) : Ctrl+Shift+X <Editing Text>
    Window End (將游標(biāo)移至視窗尾端)
    Window Start (將游標(biāo)移至視窗開頭)

    Views - 檢視
    Ant (開啟Ant檢視視窗)
    Bookmarks (開啟書籤檢視視窗)
    Breakpoints (開啟中斷點(diǎn)檢視視窗)
    Classic Search (開啟傳統(tǒng)的搜索檢視視窗)
    Console (開啟主控臺檢視視窗)
    CVS Annotate (開啟CVS Annotate檢視視窗)
    CVS Editors (開啟CVS Editor檢視視窗)
    CVS Repositories (開啟CVS Repositories檢視視窗)
    CVS Resource History (開啟CVS Resource History檢視視窗)
    Debug (開啟除錯檢視視窗)
    Display (org.eclipse.jdt.debug.ui.DisplayView) (開啟除錯-顯示檢視視窗)
    Error Log (開啟錯誤記錄檢視視窗)
    Expressions (開啟除錯-表示式檢視視窗)
    Java Call Hierarchy (開啟Call Hierarchy檢視視窗)
    Java Declaration (開啟宣告檢視視窗)
    Javadoc (開啟Javadoc檢視視窗)
    Java Members (開啟類別成員檢視視窗)
    Java Package Explorer (開啟套件瀏覽器) : Alt+Shift+Q,P <In Windows>
    Java Packages (開啟Java套件檢視視窗)
    Java Projects (開啟Java專案檢視視窗)
    Java Type Hierarchy (開啟類別階層檢視視窗) : Alt+Shift+Q,T <In Windows>
    Java Types (開啟Java類別檢視視窗)
    JUnit (開啟JUnit檢視視窗)
    Memory (開啟除錯-記憶體檢視視窗)
    Navigator (開啟導(dǎo)覽器)
    Outline (開啟概要檢視視窗) : Alt+Shift+Q,O <In Windows>
    Plug-in Dependencies (開啟Plug-in Dependencies檢視視窗)
    Plug-in Registry (開啟Plug-in Registry檢視視窗)
    Plug-ins (開啟Plug-ins檢視視窗)
    Problems (開啟問題檢視視窗) : Alt+Shift+Q,X <In Windows>
    Progress (開啟執(zhí)行進(jìn)度檢視視窗)
    Properties (org.eclipse.ui.views.Property/Sheet) (開啟屬性檢視視窗)
    Registers (開啟除錯-暫存器檢視視窗)
    Search (開啟搜索檢視視窗) : Alt+Shift+Q,S <In Windows>
    Synchronize (開啟同步化檢視視窗) : Alt+Shift+Q,Y <In Windows>
    Tasks (開啟作業(yè)檢視視窗)
    Threads and Monitors (開啟除錯-執(zhí)行緒檢視視窗)
    Variables (開啟除錯-變數(shù)檢視視窗)

    ◎補(bǔ)充:Views 檢視視窗的開啟處:
    Window->Show View->Other。

    Window - 視窗
    Activate Editor (啟動編輯器) : F12 <In Windows>
    Close All Perspectives (關(guān)閉全部視景)
    Close Perspective (關(guān)閉視景)
    Customize Perspective (自訂視景)
    Hide Editors (隱藏編輯器)
    Lock the Toolbars (鎖定工具列)
    Maximize Active View or Editor (編輯區(qū)最大化) : Ctrl+M <In Windows>
    Next Editor (切換至下一個編輯器) : Ctrl+F6 <In Windows>
    Next Perspective (切換至下一個視景) : Ctrl+F8 <In Windows>
    Next View (切換至下一個視圖) : Ctrl+F7 <In Windows>
    Open Editor Drop Down (以浮動的方式在編輯區(qū),顯示快速切換編輯器功能表) : Ctrl+E <In Windows>
    Pin Editor (固定編輯器)
    Preferences (開啟偏愛設(shè)定)
    Previous Editor (切換至上一個編輯器) : Ctrl+Shift+F6 <In Windows>
    Previous Perspective (切換至上一個視景) : Ctrl+Shift+F8 <In Windows>
    Previous View (切換至上一個視圖) : Ctrl+Shift+F7 <In Windows>
    Reset Perspective (重新設(shè)定視景)
    Save Perspective As (儲存為新視景)
    Show Ruler Context Menu (顯示尺規(guī)的內(nèi)容功能表) : Ctrl+F10 <Editing Text>
    Show Selected Element Only (僅顯示所選元素的程式碼)
    Show System Menu (顯示系統(tǒng)功能表) : Alt+- <In Windows>
    Show View Menu (顯示視圖功能表) : Ctrl+F10 <In Windows>
    Switch to Editor (切換至編輯器) : Ctrl+Shift+E <In Windows>

    posted @ 2006-09-13 20:20 ericli 閱讀(1479) | 評論 (0)編輯 收藏

    J2EE開發(fā)之常用開源項目介紹--轉(zhuǎn)載(學(xué)習(xí))

    主要還是以Spring為核心,也總結(jié)了一些以前web開發(fā)常用的開源工具和開源類庫
    ?
    1持久層:???????
    1)Hibernate
    這個不用介紹了,用的很頻繁,用的比較多的是映射,包括繼承映射和父子表映射
    對于DAO在這里介紹個在它基礎(chǔ)上開發(fā)的包bba96,目前最新版本是bba96 2.0它對Hibernate進(jìn)行了封裝, 查詢功能包括執(zhí)行hsql或者sql查詢/更新的方法,如果你要多層次邏輯的條件查詢可以自己組裝QueryObject.可以參考它做HibernateDAO.也可以直接利用它
    2) iBATIS
    另一個ORM工具,沒有Hibernate那么集成,自由度比較大,所以使用時普遍性能上比Hibernate要快一些.
    2:SpringMVC
    ?????? 原理說明和快速入門:
    ?????? 配置文件為:
    Spring的配置文件默認(rèn)為WEB-INF/xxxx-servelet.xm其中xxx為web.xml中org.springframework.web.servlet.DispatcherServlet的servlet-name。
    ?????? Action分發(fā):
    Spring將按照配置文件定義的URL,Mapping到具體Controller類,再根據(jù)URL里的action= xxx或其他參數(shù),利用反射調(diào)用Controller里對應(yīng)的Action方法。
    輸入數(shù)據(jù)綁定:
    Spring提供Binder 通過名字的一一對應(yīng)反射綁定Pojo,也可以直接從request.getParameter()取數(shù)據(jù)。
    輸入數(shù)據(jù)驗(yàn)證
    Sping 提供了Validator接口當(dāng)然還可以使用開源的Commons-Validaor支持最好
    Interceptor(攔截器)
    Spring的攔截器提供接口需要自己編寫,在這點(diǎn)不如WebWork做的好.全面
    ?????? (這里提一下WebWork和Struts的區(qū)別最主要的區(qū)別在于WebWork在建立一個Action時是新New一個對象而Struts是SingleMoule所有的都繼承它的一個Action,所以根據(jù)項目需要合適的選擇.)
    3:View層
    1) 標(biāo)簽庫:JSP2.0/JSTL
    由于Webwork或Spring的標(biāo)簽確實(shí)很有限,一般view層用JSTL標(biāo)簽,而且據(jù)說JSTL設(shè)計很好速度是所有標(biāo)簽中最快的使用起來也很簡單
    ?
    2) 富客戶端:DOJO Widgets, YUI(YahooUI),FCKEditor, Coolest日歷控件
    Dojo主要提供Tree, Tab等富客戶端控件,可以用其進(jìn)行輔助客戶端開發(fā)
    YahooUI和DOJO一樣它有自己的一套javascript調(diào)試控制臺,主要支持ajax開發(fā)也有很多Tree,Table,Menu等富客戶端控件
    FCKEditor 最流行的文本編輯器
    Coolest日歷控件 目前很多日歷控件可用,集成在項目中也比較簡單,這個只是其中的一個,界面不錯的說..
    ?
    3) JavaScript:Prototype.js
    Prototype.js作為javascript的成功的開源框架,封裝了很多好用的功能,通過它很容易編寫AJAX應(yīng)用,現(xiàn)在AJAX技術(shù)逐漸成熟,框架資源比較豐富,比如YUI,DWR等等,也是因?yàn)镴avaScript沒有合適的調(diào)試工具,所以沒有必要從零開始編寫AJAX應(yīng)用,個人認(rèn)為多用一些成熟的Ajax框架實(shí)現(xiàn)無刷新更新頁面是不錯的選擇.
    ?
    4)表格控件:Display Tag ,Extreme Table
    這兩個的功能差不多,都是View層表格的生成,界面也比較相向,可以導(dǎo)出Excel,Pdf,對Spring支持很容易.
    相比較而言比較推薦ExtremeTable,它的設(shè)計很好功能上比DisplayTag多一些,支持Ajax,封裝了一些攔截器,而且最方面的是在主頁wiki中有詳細(xì)的中文使用文檔.
    ?
    5):OSCache
    OSCache是OpenSymphony組織提供的一個J2EE架構(gòu)中Web應(yīng)用層的緩存技術(shù)實(shí)現(xiàn)組件,Cache是一種用于提高系統(tǒng)響應(yīng)速度、改善系統(tǒng)運(yùn)行性能的技術(shù)。尤其是在Web應(yīng)用中,通過緩存頁面的輸出結(jié)果,可以很顯著的改善系統(tǒng)的穩(wěn)定性和運(yùn)行性能。
    它主要用在處理短時間或一定時間內(nèi)一些數(shù)據(jù)或頁面不會發(fā)生變化,或?qū)⒁恍┎蛔兊慕y(tǒng)計報表,緩沖在內(nèi)存,可以充分的減輕服務(wù)器的壓力,防治負(fù)載平衡,快速重啟服務(wù)器(通過硬盤緩存).
    ?
    6)SiteMesh
    sitemesh應(yīng)用Decorator模式主要用于提高頁面的可維護(hù)性和復(fù)用性,其原理是用Filter截取request和response,把頁面組件head,content,banner結(jié)合為一個完整的視圖。通常我們都是用include標(biāo)簽在每個jsp頁面中來不斷的包含各種header, stylesheet, scripts and footer,現(xiàn)在,在sitemesh的幫助下,我們刪掉他們輕松達(dá)到復(fù)合視圖模式.
    Sitemesh也是 OpenSymphony的一個項目現(xiàn)在最近的版本是2.2,目前OpenSymphony自從04年就沒有更新的版本了..感覺它還是比較有創(chuàng)新的一種頁面組裝方式, OpenSymphony開源組織的代碼一般寫的比較漂亮,可以改其源代碼對自己的項目進(jìn)行適配.
    測試發(fā)現(xiàn)Sitemesh還存在一些問題,比如中文問題,它的默認(rèn)編碼是iso-8859-1在使用時候需要做一些改動.
    ?
    7)CSS,XHTML
    這個不用說了,遵循W3C標(biāo)準(zhǔn)的web頁面開發(fā).
    ?
    8)分頁標(biāo)簽: pager-taglib組件
    Pager-taglib 是一套分頁標(biāo)簽庫,可以靈活地實(shí)現(xiàn)多種不同風(fēng)格的分頁導(dǎo)航頁面,并且可以很好的與服務(wù)器分頁邏輯分離.使用起來也比較簡單.
    ?
    9)Form: Jodd Form taglib
    Jodd Form taglib使用比較簡單,只要把<form>的頭尾以<jodd:form bean= "mybean">包住
    就會自動綁定mybean, 自動綁定mybean的所有同名屬性到普通html標(biāo)記input, selectbox, checkbox,radiobox.....在這些input框里不用再寫任何代碼…
    ??????
    10)Ajax:DWR
    ?????? J2EE應(yīng)用最常用的ajax框架
    ??????
    ?????? 11)報表 圖表
    Eclipse BIRT功能比較強(qiáng)大,也很龐大..好幾十M,一般沒有特別需求或別的圖表設(shè)計軟件可以解決的不用它
    JasperReports+ iReport是一個基于Java的開源報表工具,它可以在Java環(huán)境下像其它IDE報表工具一樣來制作報表。JasperReports支持PDF、HTML、XLS、CSV和XML文件輸出格式。JasperReports是當(dāng)前Java開發(fā)者最常用的報表工具。
    JFreeChart主要是用來制作各種各樣的圖表,這些圖表包括:餅圖、柱狀圖(普通柱狀圖以及堆棧柱狀圖)、線圖、區(qū)域圖、分布圖、混合圖、甘特圖以及一些儀表盤等等。
    ??????
    ?
    4:權(quán)限控制: Acegi
    Acegi是Spring Framework 下最成熟的安全系統(tǒng),它提供了強(qiáng)大靈活的企業(yè)級安全服務(wù),如完善的認(rèn)證和授權(quán)機(jī)制,Http資源訪問控制,Method 調(diào)用訪問控制等等,支持CAS
    (耶魯大學(xué)的單點(diǎn)登陸技術(shù),這個單點(diǎn)登陸方案比較出名.我也進(jìn)行過配置使用,可以根據(jù)項目需要,如果用戶分布在不同的地方不同的系統(tǒng)通用一套登陸口令可以用它進(jìn)行解決,一般注冊機(jī)登陸機(jī)就是這樣解決的)
    ?????? Acegi只是于Spring結(jié)合最好的安全框架,功能比較強(qiáng)大,當(dāng)然還有一些其他的安全框架,這里列舉一些比較流行的是我從網(wǎng)上找到的,使用方法看其官方文檔把…
    JAAS, Seraph, jSai - Servlet Security, Gabriel, JOSSO, Kasai, jPAM, OpenSAML都是些安全控制的框架..真夠多的呵呵
    ?
    5:全文檢索
    ?????? 1) Lucene
    ?????? Lucene是一套全文索引接口,可以通過它將數(shù)據(jù)進(jìn)行倒排文件處理加入索引文件,它的索引速度和查詢速度是相當(dāng)快的,查詢百萬級數(shù)據(jù)毫秒級出結(jié)果,現(xiàn)在最火的Apache開源項目,版本更新速度很快現(xiàn)在已經(jīng)到了2.0,每個版本更新的都比較大,目前用的最多的版本應(yīng)該是1.4.3,但它有個不太方面的地方單個索引文件有2G文件限制,現(xiàn)在2.0版本沒有這個限制,我研究的比較多,它的擴(kuò)展性比較好,可以很方面的擴(kuò)充其分詞接口和查詢接口.
    ?????? 基于它的開發(fā)的系統(tǒng)很多,比如最常用的Eclipse的搜索功能,還有一些開源的軟件比如Compass,Nutch,Lius,還有我最近做的InSearch(企業(yè)級FTP文件網(wǎng)頁搜索)
    6:公共Util類
    ?????? 主要是Jakarta-Commons類庫,其中最常用得是以下幾個類庫
    1) Jakarta-Commons-Language
    ?????? 最常用得類是StringUtils類,提供了使用的字符串處理的常用方法效率比較高
    2) Jakarta-Commons-Beantuils
    ?????? 主要用Beantuils能夠獲得反射函數(shù)封裝及對嵌套屬性,map,array型屬性的讀取。
    3) Jakarta-Commons-Collections
    ?????? 里面有很多Utils方法
    ?
    7 日志管理
    ?????? Log4J
    ?????? 任務(wù)是日志記錄,分為Info,Warn,error幾個層次可以更好的調(diào)試程序
    ?
    8 開源的J2EE框架
    ?????? 1) Appfuse
    ????????????? Appfuse是Matt Raible 開發(fā)的一個指導(dǎo)性的入門級J2EE框架, 它對如何集成流行的Spring、Hibernate、iBatis、Struts、Xdcolet、JUnit等基礎(chǔ)框架給出了示范. 在持久層,AppFuse采用了Hibernate O/R映射工具;在容器方面,它采用了Spring,用戶可以自由選擇Struts、Spring/MVC,Webwork,JSF這幾個Web框架。
    ??????
    ?????? 2) SpringSide
    ?????? .SpringSide較完整的演示了企業(yè)應(yīng)用的各個方面,是一個電子商務(wù)網(wǎng)站的應(yīng)用 SpringSide也大量參考了Appfuse中的優(yōu)秀經(jīng)驗(yàn)。最重要的是它是國內(nèi)的一個開源項目,可以了解到國內(nèi)現(xiàn)在的一些實(shí)際技術(shù)動態(tài)和方向很有指導(dǎo)意義…
    ?
    9:模版 Template
    主要有Veloctiy和Freemarker
    模板用Servlet提供的數(shù)據(jù)動態(tài)地生成 HTML。編譯器速度快,輸出接近靜態(tài)HTML???????????? 頁面的速度。
    ?
    10:工作流
    ?????? 我所知道比較出名的主要有JBpm Shark Osworkflow,由于對它沒有過多的研究所以還不是很清楚之間有什么區(qū)別.
    ?
    項目管理軟件
    dotProject:是一個基于LAMP的開源項目管理軟件。最出名的項目管理軟件
    JIRA: 項目計劃,任務(wù)安排,錯誤管理
    Bugzilla:提交和管理bug,和eclipse集成,可以通過安裝MyEclipse配置一下即可使用
    BugFree借鑒微軟公司軟件研發(fā)理念、免費(fèi)開放源代碼、基于Web的精簡版Bug管理
    CVS:這個就不介紹了都在用.
    SVN: SubVersion已逐漸超越CVS,更適應(yīng)于JavaEE的項目。Apache用了它很久后,Sourceforge剛剛推出SVN的支持。
    測試用例:主要JUnit單元測試,編寫TestCase,Spring也對Junit做了很好的支持
    ?
    后記:
    ?????? 以Spring為主的應(yīng)用開發(fā)可選用的組件中間件真是眼花繚亂,所以針對不同的項目需求可以利用不同的開源產(chǎn)品解決,比如用Spring+Hibernate/ iBATIS或Spring+WebWork+Hibernate/ iBATIS或Spring+Struts+Hibernate/ iBATIS,合理的框架設(shè)計和代碼復(fù)用設(shè)計對項目開發(fā)效率和程序性能有很大的提高,也有利于后期的維護(hù).

    posted @ 2006-09-13 20:19 ericli 閱讀(552) | 評論 (1)編輯 收藏

    僅列出標(biāo)題  下一頁
    主站蜘蛛池模板: 亚洲色自偷自拍另类小说| 国产妇乱子伦视频免费| 51午夜精品免费视频| 国产精品亚洲专区在线播放| 亚洲精品无码中文久久字幕| 久久久久久亚洲精品影院| 亚洲婷婷第一狠人综合精品| 亚洲精品福利你懂| 亚洲一本到无码av中文字幕| 亚洲中文字幕AV每天更新| 亚洲一区二区三区高清在线观看 | 亚洲性日韩精品一区二区三区 | av无码久久久久不卡免费网站| 免费A级毛片无码A∨免费| 2022久久国产精品免费热麻豆| 2021国产精品成人免费视频| 日韩精品福利片午夜免费观着| 四虎免费大片aⅴ入口| 国产精品成人免费综合| 亚洲精品无码专区久久同性男| 久久精品国产亚洲5555| 亚洲成AV人片在线观看无码| 亚洲天堂久久精品| 亚洲丝袜中文字幕| 亚洲第一综合天堂另类专| 免费人成又黄又爽的视频在线电影| fc2免费人成在线| 日本免费中文视频| 在线视频观看免费视频18| 国产精品免费一级在线观看| 亚洲狠狠爱综合影院婷婷| 亚洲av色福利天堂| 亚洲一卡2卡3卡4卡国产网站| 亚洲国产aⅴ成人精品无吗| jizz18免费视频| 国产精品爱啪在线线免费观看| 好男人视频在线观看免费看片 | 50岁老女人的毛片免费观看| 九九九精品成人免费视频| 免费人成在线观看播放国产 | 亚洲成a人片在线观看老师|