<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)計(jì)

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    相冊

    收藏夾

    life

    technique

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    #

    java 基本試題

    1.通過什么參數(shù)分配Java內(nèi)存使用?
    java -Xms128m -Xmx512m

    2.Treemap和Hashmap區(qū)別是什么?
    TreeMap對Key進(jìn)行排序,而HashMap不排序。HashMap通過hashcode對其內(nèi)容進(jìn)行快速查找, 而TreeMap中所有的元素都保持著某種固定的順序,如果你需要得到一個有序的結(jié)果你就應(yīng)該 使用TreeMap(HashMap中元素的排列順序是不固定的)。

    3.為何加入:private static final long serialVersionUID?
    可以利用JDK的bin目錄下的serialver.exe工具產(chǎn)生。
    序列化時為了保持版本的兼容性,即在版本升級時反序列化仍保持 對象的唯一性。在java中serialVersionUID是唯一控制著能否反序列化成功的標(biāo)志, 只要這個值不一樣,就無法反序列化成功。

    4.JSP編譯和執(zhí)行原理?
    JSP文件的Scriptlets在編譯后將被包含于該JSP servlet的service()方法。當(dāng)JSP引擎處理客戶端請求時,JSP Scriptlets在被請求的時候被執(zhí)行。如果scriptlet產(chǎn)生輸出,輸出將在out (JSPWriter)對象中進(jìn)行緩存然后最終發(fā)送到客戶端。

    5.怎么解決JSP/Servlet web中中文亂碼的問題

    6.JDBC中,statement,prepared statement ,Callable statement的區(qū)別是什么?
    Statement 接口提供了執(zhí)行語句和獲取結(jié)果的基本方法。PreparedStatement 接口添加了處理 IN 參數(shù)的方法;而 CallableStatement 添加了處理 OUT 參數(shù)的方法。
    PreparedStatement:對于同一條語句的多次執(zhí)行,Statement每次都要把SQL語句發(fā)送給數(shù)據(jù)
    庫,這樣做效率明顯不高,而如果數(shù)據(jù)庫支持預(yù)編譯,PreparedStatement可以先把要執(zhí)行的語句一次發(fā)給它,然后每次執(zhí)行而不必發(fā)送相同的語句,效率當(dāng)然提高,當(dāng)然如果數(shù)據(jù)庫不支持預(yù)編譯,
    PreparedStatement會象Statement一樣工作,只是效率不高而不需要用戶工手干預(yù).
    ??? 另外PreparedStatement還支持接收參數(shù).在預(yù)編譯后只要傳輸不同的參數(shù)就可以執(zhí)行,大大
    提高了性能.
    CallableStatement:是PreparedStatement的子類,它只是用來執(zhí)行存儲過程的.

    7.什么情況下會拋出“打開游標(biāo)超過最大數(shù)”的異常?

    8.XML解析中:SAX和DOM的不同點(diǎn)有哪些?

    9.抽象類和接口的區(qū)別?

    10.什么是中間件

    11.JSP的內(nèi)置對象有那些?
    Out, request, response, application, session, exception, config, page, pageContext.

    12.有那些方法能防止、化解對web網(wǎng)站的攻擊?
    13.如何提高訪問web網(wǎng)站的速度?
    14.Java可采用的MVC框架技術(shù)有哪些?他們的特征和適用環(huán)境如何?
    Struts, WebWork, Spring, JSF…

    15.MVC的優(yōu)缺點(diǎn)是什么,適用范圍如何?
    MVC開發(fā)模式分離數(shù)據(jù)訪問層和數(shù)據(jù)表現(xiàn)層,并使開發(fā)人員開發(fā)一個可伸縮性的強(qiáng)、便于擴(kuò)展的控制器,來維護(hù)整個流程。
    16.TOMCAT配置中,有關(guān)安全的設(shè)置選項(xiàng)有哪些?
    17.Apach與Tomcat配合使用,是為解決什么問題?怎么實(shí)現(xiàn)?運(yùn)行過程如何?


    18.Collection的四個接口
    add();
    addAll();
    isEmpty();
    iterator();
    contains();

    19.Cookie
    20.多態(tài)
    21.Web上參數(shù)的傳輸方式
    22.HashTable和HashMap的區(qū)別
    Hashtable和HashMap類有三個重要的不同之處。第一個不同主要是歷史原因。Hashtable是基于陳舊的Dictionary類的,HashMap是Java 1.2引進(jìn)的Map接口的一個實(shí)現(xiàn)。
    也許最重要的不同是Hashtable的方法是同步的,而HashMap的方法不是。這就意味著,雖然你可以不用采取任何特殊的行為就可以在一個多線程的應(yīng)用程序中用一個Hashtable,但你必須同樣地為一個HashMap提供外同步。一個方便的方法就是利用Collections類的靜態(tài)的synchronizedMap()方法,它創(chuàng)建一個線程安全的Map對象,并把它作為一個封裝的對象來返回。這個對象的方法可以讓你同步訪問潛在的HashMap。這么做的結(jié)果就是當(dāng)你不需要同步時,你不能切斷Hashtable中的同步(比如在一個單線程的應(yīng)用程序中),而且同步增加了很多處理費(fèi)用。
    第三點(diǎn)不同是,只有HashMap可以讓你將空值作為一個表的條目的key或value。HashMap中只有一條記錄可以是一個空的key,但任意數(shù)量的條目可以是空的value。這就是說,如果在表中沒有發(fā)現(xiàn)搜索鍵,或者如果發(fā)現(xiàn)了搜索鍵,但它是一個空的值,那么get()將返回null。如果有必要,用containKey()方法來區(qū)別這兩種情況。
    23.運(yùn)行環(huán)境中的GC

    24.final,finally,finalzie的區(qū)別
    final:
    final可以讓你控制你的成員、方法或者是一個類是否可被覆寫或繼承等功能,這些特點(diǎn)使final在Java中擁有了一個不可或缺的地位,也是學(xué)習(xí)Java時必須要知道和掌握的關(guān)鍵字之一。
    final成員
    當(dāng)你在類中定義變量時,在其前面加上final關(guān)鍵字,那便是說,這個變量一旦被初始化便不可改變,這里不可改變的意思對基本類型來說是其值不可變,而對于對象變量來說其引用不可再變。其初始化可以在兩個地方,一是其定義處,二是在構(gòu)造函數(shù)中,兩者只能選其一。
    還有一種用法是定義方法中的參數(shù)為final,對于基本類型的變量,這樣做并沒有什么實(shí)際意義,因?yàn)榛绢愋偷淖兞吭谡{(diào)用方法時是傳值的,也就是說你可以在方法中更改這個參數(shù)變量而不會影響到調(diào)用語句,然而對于對象變量,卻顯得很實(shí)用,因?yàn)閷ο笞兞吭趥鬟f時是傳遞其引用,這樣你在方法中對對象變量的修改也會影響到調(diào)用語句中的對象變量,當(dāng)你在方法中不需要改變作為參數(shù)的對象變量時,明確使用final進(jìn)行聲明,會防止你無意的修改而影響到調(diào)用方法。
    final方法
    將方法聲明為final那有兩個原因,第一就是說明你已經(jīng)知道這個方法提供的功能已經(jīng)滿足你要求,不需要進(jìn)行擴(kuò)展,并且也不允許任何從此類繼承的類來覆寫這個方法,但是繼承仍然可以繼承這個方法,也就是說可以直接使用。第二就是允許編譯器將所有對此方法的調(diào)用轉(zhuǎn)化為inline(行內(nèi))調(diào)用的機(jī)制,它會使你在調(diào)用final方法時,直接將方法主體插入到調(diào)用處,而不是進(jìn)行例行的方法調(diào)用,例如保存斷點(diǎn),壓棧等,這樣可能會使你的程序效率有所提高,然而當(dāng)你的方法主體非常龐大時,或你在多處調(diào)用此方法,那么你的調(diào)用主體代碼便會迅速膨脹,可能反而會影響效率,所以你要慎用final進(jìn)行方法定義。
    final類
    當(dāng)你將final用于類身上時,你就需要仔細(xì)考慮,因?yàn)橐粋€final類是無法被任何人繼承的,那也就意味著此類在一個繼承樹中是一個葉子類,并且此類的設(shè)計(jì)已被認(rèn)為很完美而不需要進(jìn)行修改或擴(kuò)展。對于final類中的成員,你可以定義其為final,也可以不是final。而對于方法,由于所屬類為final的關(guān)系,自然也就成了final型的。你也可以明確的給final類中的方法加上一個final,但這顯然沒有意義。

    finally:
    finally 關(guān)鍵字是對 Java 異常處理模型的最佳補(bǔ)充。 finally 結(jié)構(gòu)使代碼總會執(zhí)行,而不管有無異常發(fā)生。使用 finally 可以維護(hù)對象的內(nèi)部狀態(tài),并可以清理非內(nèi)存資源。如果沒有 finally,您的代碼就會很費(fèi)解。例如,下面的代碼說明,在不使用 finally 的情況下您如何編寫代碼來釋放非內(nèi)存資源:

    finalize:
    根據(jù)Java語言規(guī)范,JVM保證調(diào)用finalize函數(shù)之前,這個對象是不可達(dá)的,但是JVM不保證這個函數(shù)一定會被調(diào)用。另外,規(guī)范還保證finalize函數(shù)最多運(yùn)行一次。
    通常,finalize用于一些不容易控制、并且非常重要資源的釋放,例如一些I/O的操作,數(shù)據(jù)的連接。這些資源的釋放對整個應(yīng)用程序是非常關(guān)鍵的。在這種情況下,程序員應(yīng)該以通過程序本身管理(包括釋放)這些資源為主,以finalize函數(shù)釋放資源方式為輔,形成一種雙保險(xiǎn)的管理機(jī)制,而不應(yīng)該僅僅依靠finalize來釋放資源。

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

    富客戶端技術(shù)(之一)   FCKEditor   最流行的文本編輯器

    ?????C/S體系結(jié)構(gòu)采用了開放的模式在一定的程度上解決了人們對聯(lián)機(jī)辦公等的網(wǎng)絡(luò)應(yīng)用需求,導(dǎo)致了胖客戶端應(yīng)用(fat clients)流行。
    ????隨著人們對網(wǎng)絡(luò)應(yīng)用需求的進(jìn)一步深入,B/S結(jié)構(gòu)的網(wǎng)絡(luò)應(yīng)用又隨之誕生了,這種結(jié)構(gòu)的網(wǎng)絡(luò)應(yīng)用又稱為瘦客戶端應(yīng)用,只要通過Web瀏覽器,各種處理任務(wù)都可以調(diào)用系統(tǒng)資源來完成,這樣大大簡化了客戶端,減輕了系統(tǒng)維護(hù)與升級的成本和工作量,降低了用戶的總體擁有成本(TCO)。
    ????今天的網(wǎng)絡(luò)應(yīng)用需要從“什么都用Web瀏覽器”到“根據(jù)情況采用強(qiáng)化客戶端技術(shù)”進(jìn)行本質(zhì)的轉(zhuǎn)變。人們需要更為復(fù)雜而精美的應(yīng)用交互界面,發(fā)布和表現(xiàn)多種復(fù)雜形式的多媒體和內(nèi)容,對形式多樣而豐富的信息內(nèi)容進(jìn)行更好的組織和表現(xiàn),而這些正是目前廣泛應(yīng)用的B/S結(jié)構(gòu)所不能達(dá)到的,于是富客戶端技術(shù)應(yīng)運(yùn)而生。
    ???作為開源的j2ee技術(shù)中涉及到view層的富客戶端是一種趨勢,而今天要介紹就是其中的一個簡單的開源技術(shù)FCKEditor,運(yùn)用它,可以在你的的頁面展示出類似word頁面的效果,而且無須安裝,只需要在你的項(xiàng)目中引入相關(guān)的jar文件,在需要控件的地方適當(dāng)?shù)恼{(diào)用就可以了。
    ???下面我做一個簡單的演示給大家
    ???1.首先,我們先去了解一下FCKEditor   http://www.fckeditor.net/
    ???英文介紹簡單明了:
    ???This HTML text editor brings to the web many of the powerful functionalities of desktop editors like MS Word.
    It's lightweight and doesn't require any kind of installation on the client computer.??
    ???2.然后去下載相關(guān)的文件,這里我下載的是FCKeditor_2.3.1.zip文件
    ???3.解壓文件,本人使用的jsp頁面,還需要下載 FCKeditor.Java 的相關(guān)文件
    ???4.從sample01.jsp開始,使用中來體會學(xué)習(xí)
    ************************************jsp頁面*********************************************
    ?
    <%@ page language="java" import="com.fredck.FCKeditor.*" %>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html>
    ?<head>
    ??<title>FCKeditor - JSP Sample</title>
    ??<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    ??<meta name="robots" content="noindex, nofollow">
    ??<link href="../sample.css" rel="stylesheet" type="text/css" />
    ??<script type="text/javascript">

    function FCKeditor_OnComplete( editorInstance )
    {
    ?window.status = editorInstance.Description ;
    }

    ??</script>
    ?</head>
    ?<body>
    ??<h1>FCKeditor - JSP - Sample 1</h1>
    ??This sample displays a normal HTML form with an FCKeditor with full features
    ??enabled.
    ??<hr>
    <!--? 自己的 action 方式? -->
    ??<form action="sampleposteddata.jsp" method="get" target="_blank">
    <%
    //以下是修改的關(guān)鍵
    FCKeditor oFCKeditor ;
    oFCKeditor = new FCKeditor( request, "EditorDefault" ) ;//初始化的一些配置,第二個參數(shù)EditorDefault就是這個字段的名稱
    oFCKeditor.setBasePath( "/FCKeditor/" ) ;//為了尋找相應(yīng)的frame頁面:fckeditor.html;同時傳遞參數(shù);這里設(shè)置為我們需要的路徑!
    //oFCKeditor.setBasePath( "/nhoa/FCKeditor/" ) ;//我的例子,就是指明你的文件放在哪個目錄下
    oFCKeditor.setValue( "ligang's example!" );//初始化頁面顯示的數(shù)據(jù)
    out.println( oFCKeditor.create() ) ;//建立吧,看源碼很簡單!
    %>
    ???<br>
    ???<input type="submit" value="Submit">
    ??</form>
    ?</body>
    </html>
    ************************************jsp頁面***********************************

    使用步驟:
    (1)項(xiàng)目中import 這個包包:fckEditor.jar(將src的java代碼打包),需要看源碼也可以!
    (2)修改你的jsp頁面,在需要添加該效果的地方模仿以上jsp頁面進(jìn)行修改
    (3)想想,好象沒有什么事了!
    (4)試試吧!
    5.分析實(shí)現(xiàn)原理
    主要就是oFCKeditor.create()?,通過這個方法建立控件,在源代碼中可以看見
    public String create() {
    ??StringBuffer strEditor=new StringBuffer();
    ??
    ??strEditor.append("<div>");
    ??String encodedValue=HTMLEncode(value);

    ???if(isCompatible()) {?//瀏覽器版本符合要求產(chǎn)生我們的控件
    ???strEditor.append("<input type=\"hidden\" id=\"" + instanceName + "\" name=\"" + instanceName + "\" value=\"" + encodedValue + "\">");
    ??
    ???strEditor.append(createConfigHTML());
    ???strEditor.append(createIFrameHTML());
    ??
    ??}
    ??else{//瀏覽器版本不符合要求,產(chǎn)生一個textarea,呵呵,也不失是一種彌補(bǔ)的方式
    ???strEditor.append("<TEXTAREA name=\"" + instanceName + "\" rows=\"4\" cols=\"40\" style=\"WIDTH: " + width + "; HEIGHT: " + height + "\" wrap=\"virtual\">"+encodedValue+"</TEXTAREA>");
    ??}
    ??strEditor.append("</div>");
    ??return strEditor.toString();
    ?}
    ???其實(shí)就是一個servelt向?yàn)g覽器寫一些html語句,其中的createConfigHTML()就是通過配置文件config.js向控件傳遞一些參數(shù),在頁面是通過hidden域來傳遞的,但是自己沒有找到這個文件的位置,希望明白的朋友可以告訴我......
    createIFrameHTML()就是建立控件的方法,其中最重要的一個參數(shù)就是sLink,
    String sLink=basePath + "editor/fckeditor.html?InstanceName=" + instanceName;它指明了控件數(shù)據(jù)的名稱就是instanceName,它有時在那里被用戶初始化的呢,呵呵,是在構(gòu)造方法里面,F(xiàn)CKeditor 類有一個構(gòu)造方法
    ?public FCKeditor(HttpServletRequest req, String parInstanceName){
    ??request=req;
    ??basePath = request.getContextPath() + "/FCKeditor/";
    ??instanceName=parInstanceName;
    ??oConfig = new FCKeditorConfigurations() ;
    ?}
    我們在jsp頁面上,看到
    oFCKeditor = new FCKeditor( request, "EditorDefault" ) ;//初始化的一些配置,第二個參數(shù)EditorDefault就是這個
    變量
    6.到這里,需要我們試用者了解的部分就這些了,剩下的工作就是控件自己實(shí)現(xiàn)了,呵呵,真的很簡單啊
    總結(jié):
    使用就要做兩件事情:import fckEditor.jar,這個jar包是我自己通過開源的代碼自己編譯后打的
    還有就是在需要的地方添加代碼,注意兩個地方,一個是選取合適的構(gòu)造函數(shù)和構(gòu)造函數(shù)參數(shù),還有就是
    設(shè)定好自己項(xiàng)目擺放FCKeditor文件的目錄,基本沒有什么問題,今天在工作的項(xiàng)目上使用了一下沒有什么問題.

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

    tomcat 4.1.30啟動過程的源碼分析

    前幾天為了解決sinpool兄的《多線程的問題。》一帖,專門看了一下tomcat 4.1.30的源碼,
    其中重點(diǎn)研究了tomcat的啟動這一部分,個人感覺tomcat的源碼還是寫的很清楚易懂,值得一看。
    (以前看過struts的部分代碼,感覺也比較經(jīng)典)????
    然后我看后的代碼整理了一下,附在下面,希望對其他人有用,也希望感興趣的兄弟可以多看看好的代碼,
    肯定對自己的程序設(shè)計(jì)和代碼質(zhì)量頗有益處。

    一. 啟動類(包含main()方法的類):
    org.apache.catalina.startup.Bootstrap
    這個類是tomcat的啟動類,主要按照如下步驟,進(jìn)行主要的啟動工作:
    1. 創(chuàng)建3個ClassLoader:common,catalina和share,它們對應(yīng)tomcat的3個Classloader,我想對tomcat
    的classloader有研究的兄弟對這個肯定不陌生,其中common classloader是緊跟在系統(tǒng)的classloader(也就是
    系統(tǒng)環(huán)境變量中設(shè)置的CLASSPATH所對應(yīng)的classloader),而catalina classloader是common的子classloader,是tomcat
    運(yùn)行所需要的類的classloader,而shared classloader也是common的子classloader,是和catalina平級的classloader,
    之所以說是shared classloader,是因?yàn)樗撬衪omcat下面發(fā)布的webapp classloader(每一個web app都有一個自己的classloader)
    的父classloader。它們這3個classloader分別讀取tomcat home下面的common, server和shared三個目錄里面的classes和lib目錄,
    用于初始化自己所控制的類庫和資源。

    2. 創(chuàng)建啟動一個的org.apache.catalina.startup.Catalina類的實(shí)例,并調(diào)用它的process方法,這里使用的是java的reflection技術(shù)。
    然后調(diào)用這個實(shí)例的process方法,并把Bootstrap接受到的命令行參數(shù)傳遞進(jìn)去了,這里Bootstrap類并沒有解析傳給它的命令行參數(shù)。
    當(dāng)然在調(diào)用process之前還使用setParentClassLoader方法設(shè)置了一下父classloader。這里簡單介紹一下有關(guān)classloader的一個重要
    特性,就是如果classloader要load一個類時,不是自己先找,而是先把這個任務(wù)委派給自己的父classloader,然后自己的父classloader
    也不找,在把這個任務(wù)委派給自己的父classloader,直到找到最頂層的classloader,然后再自頂向下的找對應(yīng)的這個要load的類的定義,
    如果那個classloader先找到,就返回。所以接合上面第一點(diǎn)介紹的tomcat中3個classloader,大家就可以明白tomca的classloader找類
    的順序了,這個對程序開發(fā)人員來說特別重要。我想使用過tomcat或者其他app server的兄弟肯定碰到過一個類明明存在可就是找不到,
    或者總是找到一個老的版本,我想主要是在多個地方放置的原因,或者哪里有重名的類:-)

    二.org.apache.catalina.startup.Catalina類
    現(xiàn)在程序轉(zhuǎn)到org.apache.catalina.startup.Catalina類里面的process方法。
    這個方法首先設(shè)置一下catalina的home和base目錄,然后通過arguments方法解析命令行參數(shù),
    最后調(diào)用execute()方法啟動server。而execute方法很簡單,就是根據(jù)arguments解析的命令行參數(shù),
    決定是啟動server,還是stop server,如果是start server,就調(diào)用start方法,而下面重點(diǎn)講一下這個start()方法,
    因?yàn)椴潘闶且粋€真正開始的啟動tomcat的地方:-)
    1. start方法首先使用Digester(這個東東是jakarta commons里面的一個用于解析xml文件的工具包,一開始是專門用于解析struts配置文件的,
    后來被抽象成現(xiàn)在的一個通用工具,主要還是用來解析xml配置文件,根據(jù)一些定義的rule自動生成對應(yīng)的類的實(shí)例,具體信息可以參考
    apache網(wǎng)站上的文檔)來設(shè)置tomcat配置文件,也就是/conf/server.xml這個文件的解析規(guī)則
    然后通過如下代碼來將配置文件中的數(shù)據(jù)轉(zhuǎn)化成內(nèi)存中的實(shí)例:

    代碼:
    ??????? File file = configFile();

    ??????? try {

    ??????????? InputSource is =

    ??????????????? new InputSource("file://" + file.getAbsolutePath());

    ??????????? FileInputStream fis = new FileInputStream(file);

    ??????????? is.setByteStream(fis);

    ??????????? digester.push(this);

    ??????????? digester.parse(is);

    ??????????? fis.close();

    ??????? } catch (Exception e) {

    ??????????? System.out.println("Catalina.start: " + e);

    ??????????? e.printStackTrace(System.out);

    ??????????? System.exit(1);

    ??????? }???
    ????
    ?


    轉(zhuǎn)換的規(guī)則如下(我只作一些簡單的介紹),例如配置文件中的
    a. Server對應(yīng)可以產(chǎn)成一個org.apache.catalina.core.StandardServer類(這個類很重要,是tomcat server的實(shí)現(xiàn))
    b. Server/GlobalNamingResources對應(yīng)生成org.apache.catalina.deploy.NamingResources類
    而大家比較熟悉的監(jiān)聽8080端口的類配置如下:
    c. Server/Service/Connector:org.apache.catalina.connector.http.HttpConnector
    d. Server/Service/Engine/Host/Context/:org.apache.catalina.core.StandardContext
    有興趣的兄弟可以參考jakarta commons里面的Digester文檔和org.apache.catalina.startup.Catalina
    這個類里面的createStartDigester方法.
    在這段代碼之后,一個叫server的變量已經(jīng)通過Digester工具生成了,它將會用于啟動tomcat。
    2. 然后程序進(jìn)行了一些server啟動前的設(shè)置工作,例如重定向log輸出流等等。而server啟動的代碼如下:

    代碼:
    ??????? // Start the new server

    ??????? if (server instanceof Lifecycle) {

    ??????????? try {

    ??????????????? server.initialize();

    ??????????????? ((Lifecycle) server).start();

    ??????????????? try {

    ??????????????????? // Register shutdown hook

    ??????????????????? Runtime.getRuntime().addShutdownHook(shutdownHook);

    ??????????????? } catch (Throwable t) {

    ??????????????????? // This will fail on JDK 1.2. Ignoring, as Tomcat can run

    ??????????????????? // fine without the shutdown hook.

    ??????????????? }

    ??????????????? // Wait for the server to be told to shut down

    ??????????????? server.await();

    ??????????? } catch (LifecycleException e) {

    ??????????????? System.out.println("Catalina.start: " + e);

    ??????????????? e.printStackTrace(System.out);

    ??????????????? if (e.getThrowable() != null) {

    ??????????????????? System.out.println("----- Root Cause -----");

    ??????????????????? e.getThrowable().printStackTrace(System.out);

    ??????????????? }

    ??????????? }

    ??????? }

    ????
    ?


    其中server這個變量就是在剛才Digester解析時創(chuàng)建好的。
    (當(dāng)時這個地方我看了很長時間,后來才發(fā)現(xiàn)是這樣的,因?yàn)橐郧安惶私釪igester這個東東)。
    然后大家可以看到server啟動主要是分3步:
    1. initialize方法進(jìn)行server啟動的初始化操作
    2. start方法啟動server,主要是server中的的service和service中的connector
    3. await方法等待server shutdown
    其中我重點(diǎn)給大家介紹一下initialize方法和start方法
    initialize方法:
    這里面只有一個主要任務(wù),就是逐次調(diào)用server中所有定義的service的initialize方法,
    而每個service的initialize方法中調(diào)用這個service中定義的所有connector的initialize方法,
    而connector的initialize方法則是創(chuàng)建一個serversocket用于接受客戶端的請求就結(jié)束了。
    如果大家看一下tomcat下面conf/server.xml,就可以發(fā)現(xiàn),tomcat默認(rèn)只定義了一個service叫做Tomcat-Standalone,
    而下面只有默認(rèn)定義了3個connector:
    1. 8080端口的http connector
    2. 8443端口的http ssl connector
    3. 8009端口的Coyote/JK2 AJP 1.3 Connector
    我想大家對這3個端口一定不陌生吧。
    start方法:
    這個方法里面有一個tomcat很重要,也是我認(rèn)為tomcat設(shè)計(jì)對一個亮點(diǎn),就是Lifecycle這個東東,它很象一個bus(總線)。
    我想大家進(jìn)行過程序設(shè)計(jì)的一定知道,開始設(shè)計(jì)的時候總要根據(jù)一個原則分出幾個模塊來,是為了代碼分塊,或者將
    一部分功能相似的代碼組織成一個模塊,這樣比較清楚,例如一個進(jìn)銷存系統(tǒng)會有采購,銷售,庫存和財(cái)務(wù)等模塊,但是
    我想很多人也碰到過這樣的情況就是雖然分了模塊但是如果在開發(fā)完畢以后,另外一個客戶說只想要其中的銷售模塊,我想
    大部分的開發(fā)人員肯定傻眼,因?yàn)殡m然當(dāng)時設(shè)計(jì)的時候分了模塊,但是這些模塊編寫的時候卻是交織在一起,互相的接口定義
    很模糊,基本上都是直接調(diào)用另一個模塊的方法,這樣肯定分不開。而tomcat的這個Lifecycle的設(shè)計(jì)理念就可以解決這個問題的
    一部分,它的原理就象是一個bus(總線),例如一個模塊做完一個動作以后,例如銷售模塊創(chuàng)建好一個訂單后,本來要直接調(diào)用
    庫存模塊的api鎖住一部分庫存(我只是隨便舉個例子,實(shí)際業(yè)務(wù)不一定是這樣),這樣銷售模塊就需要依賴庫存模塊了。但是使用了
    bus方式。我們就可以在訂單創(chuàng)建后,向bus上發(fā)送一個訂單創(chuàng)建的消息,而總線有一個事件注冊機(jī)制,有點(diǎn)象swing的event,listener,
    例如庫存模塊有一個listener專門用于監(jiān)聽訂單創(chuàng)建的消息,進(jìn)行處理,這樣2個模塊就互不依賴了。有興趣的兄喜可以看看jcp上面
    的一個叫做infobus的專題。
    當(dāng)然這個方式只是解決有效降低模塊偶合度的一個方面(因?yàn)橛械臅r候必須要直接調(diào)用另外一個模塊的接口,
    例如庫存模塊一定要直接缺德一個銷售訂單的信息,那么就需要定義一個接口類來描述訂單的詳細(xì)信息啦,這里就不具體解釋了,
    有空可以專門發(fā)個帖子跟大家探討這個問題:-) ),就是不要顯式觸發(fā)另一個模塊的某個動作,而是通過bus機(jī)制來發(fā)送消息,
    而每個模塊都有一個自己的handler,會監(jiān)聽bus,對自感興趣的事件進(jìn)行處理。tomcat的Lifecycle就是這個東西。
    下面再回到start方法:
    1. 它首先向總線發(fā)送了2個事件:BEFORE_START_EVENT和START_EVENT
    2. 然后調(diào)用每個service的start方法,最后發(fā)送AFTER_START_EVENT消息通知其他程序
    而service的start方法主要進(jìn)行的動作如下:
    1. 發(fā)送BEFORE_START_EVENT消息
    2. 調(diào)用container的start方法
    3. 然后調(diào)用connector的start方法
    4. 最后發(fā)送AFTER_START_EVENT消息.
    而connector的start方法就是大家最熟悉的socket編程了,大家可以參看org.apache.catalina.connector.http.HttpConnector這個類,
    主要是使用java里面的多線程操作,初始化一個HttpProcessor的線程池,然后通過wait方法阻塞住每個HttpProcessor線程,只有
    當(dāng)接受到一個http請求時,在通過notify方法激活HttpProcessor線程,讓其處理用戶的http請求。

    到此為止主要簡單介紹了一下tomcat 4.1.30的啟動過程,下次有機(jī)會的話,可以再看看它的webapp的deploy的管理部分的代碼,然后和大家分享。如果大家對我寫的帖子有什么意見的話,也歡迎批評指正,希望感興趣的兄弟可以一起探討:-) 廢話不說了,很晚了該睡覺了,祝大家周一工作愉快

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

    僅列出標(biāo)題
    共2頁: 上一頁 1 2 
    主站蜘蛛池模板: 亚洲αv久久久噜噜噜噜噜| free哆啪啪免费永久| 四虎成人精品国产永久免费无码| 亚洲中文字幕久久久一区| 亚洲av永久无码精品三区在线4 | 成年轻人网站色免费看| 又粗又大又黑又长的免费视频 | 国产精品午夜免费观看网站| 羞羞视频免费网站日本| 一级做a爰片久久毛片免费陪 | 怡红院亚洲红怡院在线观看| 色婷婷六月亚洲综合香蕉| 亚洲a∨无码一区二区| 亚洲av无码一区二区三区人妖| 直接进入免费看黄的网站| 一边摸一边爽一边叫床免费视频| 一级做a免费视频观看网站| 好吊色永久免费视频大全 | 亚洲乱色伦图片区小说| 亚洲成在人线在线播放无码 | wwwxxx亚洲| 亚洲精品无码少妇30P| 豆国产96在线|亚洲| jizz免费在线影视观看网站| 三级网站在线免费观看| 中文字幕免费在线| 无码人妻久久一区二区三区免费丨 | 一级特级aaaa毛片免费观看 | 国产精品亚洲专区无码不卡| 九九综合VA免费看| 毛片在线全部免费观看| 精品久久久久成人码免费动漫| 国产高清免费观看| 亚洲午夜国产精品无码| 亚洲欧洲日产国码二区首页| 亚洲中文字幕AV每天更新| 一级看片免费视频囗交| 97在线视频免费公开观看| 日韩中文字幕免费| 国产精品亚洲成在人线| 亚洲人成网网址在线看|