Tomcat6 源碼學習(一)

Tomcat6 源碼學習
2010-3-29
【tomcat啓動類Bootstrap】
t1.tomcat的人口函數,啓動類
org.apache.catalina.startup. Bootstrap.java   Main函數

t2.Bootstrap類
初始化 ClassLoader, 然後利用 Java Reflection 調用 Catalina 類來啓動 tomcat server

【tomcat擴展-日誌】
a1.private static Log log = LogFactory.getLog(Bootstrap.class);
日誌可以定義爲private 和static

a2.只在本類中使用的方法,使用private,降低訪問權限,需要的時候,再考慮重構或者提高訪問權限public

a.日誌打印前加if(log.isInfoEnabled())
如果代碼中含有logger.debug(“string”);此類語句,儘管在log4j.xml配置文件中對該類logger的level爲 ERROR,但是仍然會產生較大的內存開銷,通常是所要輸出的string的幾十倍甚至上百倍大小,對內存開銷非常大。優化方法爲:使用logger進行 判斷。


2010-3-30
【tomcat擴展-classloader】
a3.如果兩個類屬於同一個包下,但是由不同的classloader加載,那麼他們也不能互訪default類型方法,屬性

a4.classloader:與C或C++編寫的程序不同,Java程序並不是一個可執行文件,而是由許多獨立的類文件組成,每一個文件基本上 對應於一個類。此外,這些類文件並非立即全部都裝入內存,而是根據程序需要裝入內存。ClassLoader是JVM中將類裝入內存的那部分

a5.定製的ClassLoader應用:
1.在執行非置信代碼之前,自動驗證數字簽名
2.使用用戶提供的密碼透明地解密代碼
3.動態地創建符合用戶特定需要的定製化構建類
4.任何您認爲可以生成Java字節碼的內容都可以集成到應用程序中

a6.findClass方法是創建定製的ClassLoader時唯一需要覆蓋的方法。
ClassLoader loadClass方法
Class c = findLoadedClass(name);
if (c == null) {
    try {
if (parent != null) {
    c = parent.loadClass(name, false);
} else {
    c = findBootstrapClass0(name);
}
    } catch (ClassNotFoundException e) {
        // If still not found, then invoke findClass in order
        // to find the class.
        c = findClass(name);
    }
}

a7.ClassLoader(CCL)的任務是確保代碼被編譯和更新。
下面描述了它的工作方式:1、當請求一個類時,先查看它是否在磁盤的當前目錄或相應的子目錄。
2、如果該類不存在,但源碼中有,那麼調用Java編譯器來生成類文件。
3、如果該類已存在,檢查它是否比源碼舊。如果是,調用Java編譯器來重新生成類文件。
4、如果編譯失敗,或者由於其它原因不能從現有的源碼中生成類文件,返回ClassNotFoundException。
5、如果仍然沒有該類,也許它在其它庫中,所以調用findSystemClass來尋找該類。
6、如果還是沒有,則返回ClassNotFoundException。
7、否則,返回該類。
8、調用findLoadedClass來查看是否存在已裝入的類。
9、如果沒有,那麼採用那種特殊的神奇方式來獲取原始字節。
10、如果已有原始字節,調用defineClass將它們轉換成Class對象。
11、如果沒有原始字節,然後調用findSystemClass查看是否從本地文件系統獲取類。
12、如果resolve參數是true,那麼調用resolveClass解析Class對象。
13、如果還沒有類,返回ClassNotFoundException。
14、否則,將類返回給調用程序。

【tomcat啓動類classloader】
t3.tomcat自定義了三個類,catalinaLoader commonLoader,sharedLoader
Common - 載入$CATALINA_HOME/common/...它們對TOMCAT和所有的WEB APP都可見
Catalina - 載入$CATALINA_HOME/server/..它們僅對TOMCAT可見,對所有的WEB APP都不可見
Shared-載入$CATALINA_HOME/shared/它們僅對所有WEB APP可見,對TOMCAT不可見(也不必見)

t4.Bootstrap通過反射初始化Catalina類,
反射調用Catalina方法setParentClassLoader,傳遞SharedClassloader
反射call Catalina方法load 利用server.xml中的配置初始化Service,Server,Engine,Host
反射call Catalina方法start Start the new server  該server是通過  解析xml文件生成的org.apache.catalina.core.StandardServer類


【tomcat-xml解析】
1.Tomcat取了Digester中的interface和幾個Rule,並且自己實現了一些 Rule 來解析xml.
2.tomcat解析xml創建以下幾個類
Server:
org.apache.catalina.core.StandardServer
Resources:
org.apache.catalina.deploy.NamingResources
Server's Listener:( 監聽server事件)
org.apache.catalina.core.AprLifecycleListener
org.apache.catalina.core.JasperListener
org.apache.catalina.mbeans.ServerLifecycleListener
org.apache.catalina.mbeans.GlobalResourcesLifecycleListener
Service:
org.apache.catalina.core.StandardService
Executor:
org.apache.catalina.core.StandardThreadExecutor
Engine:
org.apache.catalina.core.StandardEngine
Connector:
org.apache.catalina.connector.Connector

【tomcat-流程】
3.StandardServer啓動StandardService,StandardService啓動Connector,
Connector啓動Http11Protocol,Http11Protocol啓動JIoEndpoint,
JioEndpoint啓動server Socket,listern 8080端口,處理http請求

4.Http11Processor
Processes HTTP requests.
由http11ConnectionHandler調用,Http11ConnectionHandler由JioEndpoint中的Work 調用

5.A connector passes the request and reponse objects to the Container by calling the Container interface's invoke method
public void invoke(Request request, Response response)
        throws IOException, ServletException;

inside the invoke method ,the container loads the servlet class,call its sevice method ,manage sessions,etc.

6.Connector 方法initialize中
// Initializa adapter
adapter = new CoyoteAdapter(this);
protocolHandler.setAdapter(adapter);
adapter通過protocolHandler(Http11Protocol)傳給Http11Processor,
Http11Processor解析,create request和response,通過adapter傳送給Container

7.Tomcat使用Pipeline模式在各層容器間傳遞請求,將請求通過管道依次通過Engine,Host,Context和 Wrapper。另外,每一個容器  
都可以設置一系列的Valve去對請求進行攔 截,就像管道中的閥一樣對請求的行爲進行一些干涉。


2010-3-31
【tomcat-流程】
1.tomcat的pipeline/valve是標準的責任鏈模式,每個級別的容器中pipeline所有的valve都完成動作後會將 request/response傳到下一個容器的pipeline中的valve,
這樣一直傳遞下去直到Wrapper的BaseValve.
Ps:每個容器的BaseValve會調用下個容器的起始valve

2.StandardEngine
屬性Pipeline  pipeline = new StandardPipeline(this);
構造函數裏會設置最底層的閥門
pipeline.setBasic(new StandardEngineValve());
如果需要設置新閥門處理需求,只需要調用 pipeline.addValve(Valve valve);

3.CoyoteAdapter中會執行
connector.getContainer().getPipeline().getFirst().invoke(request, response);
該行代碼會一層一層調用添加的閥門,處理下去.

2010-4-1
【tomcat-流程】
1.jk插件負責tomcat和其它http容器進行通信

2.連接器協議AJP/1.3是tomcat用來與其它http容器進行連接的協議

3.把指定Context的classloader付給當前線程。
Thread.currentThread().setContextClassLoader(context.getLoader().getClassLoader()); 這樣request就只看見指定的context下面的classes和jar包,而看不見tomcat本身的類。

2010-4-7
【tomcat-socke與worker線程】
/**
* Process an incoming TCP/IP connection on the specified socket.  Any
* exception that occurs during processing must be logged and swallowed.
* <b>NOTE</b>:  This method is called from our Connector's thread.  We
* must assign it to our own thread so that multiple simultaneous
* requests can be handled.
* @param socket TCP socket to process
*/
synchronized void assign(Socket socket) {
// Wait for the Processor to get the previous Socket
while (available) {
try {
              wait();
       } catch (InterruptedException e) {
       }
    }
    // Store the newly available Socket and notify our thread
    this.socket = socket;
    available = true;
    notifyAll();
}

/**
* Await a newly assigned Socket from our Connector, or <code>null</code
* if we are supposed to shut down.
*/
private synchronized Socket await() {
// Wait for the Connector to provide a new Socket
while (!available) {
try {
wait();
} catch (InterruptedException e) {
}
}
    // Notify the Connector that we have received this Socket
    Socket socket = this.socket;
    available = false;
    notifyAll();
return (socket);
}
連接器線程調用worker類的assign類,worker類的執行線程run方法會調用await方法獲取socket,通過 available變量的設置和wait/notify方法來協調彼此的操作。當連接器線程未傳輸socket,worker類線程就執行wait等待,
當worker類執行線程在處理忙的時候,連接器線程wait。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章