|
【tomcat啟動(dòng)類Bootstrap】 t1.tomcat的人口函數(shù),啟動(dòng)類 org.apache.catalina.startup. Bootstrap.java Main函數(shù) t2.Bootstrap類 初始化 ClassLoader, 然后利用 Java Reflection 調(diào)用 Catalina 類來(lái)啟動(dòng) tomcat server 【tomcat擴(kuò)展-日志】 a1.private static Log log = LogFactory.getLog(Bootstrap.class); 日志可以定義為private 和static a2.只在本類中使用的方法,使用private,降低訪問權(quán)限,需要的時(shí)候,再考慮重構(gòu)或者提高訪問權(quán)限public a.日志打印前加if(log.isInfoEnabled()) 如果代碼中含有l(wèi)ogger.debug(“string”);此類語(yǔ)句,盡管在log4j.xml配置文件中對(duì)該類logger的level為 ERROR,但是仍然會(huì)產(chǎn)生較大的內(nèi)存開銷,通常是所要輸出的string的幾十倍甚至上百倍大小,對(duì)內(nèi)存開銷非常大。優(yōu)化方法為:使用logger進(jìn)行 判斷。 2010-3-30 【tomcat擴(kuò)展-classloader】 a3.如果兩個(gè)類屬于同一個(gè)包下,但是由不同的classloader加載,那么他們也不能互訪default類型方法,屬性 a4.classloader:與C或C++編寫的程序不同,Java程序并不是一個(gè)可執(zhí)行文件,而是由許多獨(dú)立的類文件組成,每一個(gè)文件基本上 對(duì)應(yīng)于一個(gè)類。此外,這些類文件并非立即全部都裝入內(nèi)存,而是根據(jù)程序需要裝入內(nèi)存。ClassLoader是JVM中將類裝入內(nèi)存的那部分 a5.定制的ClassLoader應(yīng)用: 1.在執(zhí)行非置信代碼之前,自動(dòng)驗(yàn)證數(shù)字簽名 2.使用用戶提供的密碼透明地解密代碼 3.動(dòng)態(tài)地創(chuàng)建符合用戶特定需要的定制化構(gòu)建類 4.任何您認(rèn)為可以生成Java字節(jié)碼的內(nèi)容都可以集成到應(yīng)用程序中 a6.findClass方法是創(chuàng)建定制的ClassLoader時(shí)唯一需要覆蓋的方法。 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)的任務(wù)是確保代碼被編譯和更新。 下面描述了它的工作方式:1、當(dāng)請(qǐng)求一個(gè)類時(shí),先查看它是否在磁盤的當(dāng)前目錄或相應(yīng)的子目錄。 2、如果該類不存在,但源碼中有,那么調(diào)用Java編譯器來(lái)生成類文件。 3、如果該類已存在,檢查它是否比源碼舊。如果是,調(diào)用Java編譯器來(lái)重新生成類文件。 4、如果編譯失敗,或者由于其它原因不能從現(xiàn)有的源碼中生成類文件,返回ClassNotFoundException。 5、如果仍然沒有該類,也許它在其它庫(kù)中,所以調(diào)用findSystemClass來(lái)尋找該類。 6、如果還是沒有,則返回ClassNotFoundException。 7、否則,返回該類。 8、調(diào)用findLoadedClass來(lái)查看是否存在已裝入的類。 9、如果沒有,那么采用那種特殊的神奇方式來(lái)獲取原始字節(jié)。 10、如果已有原始字節(jié),調(diào)用defineClass將它們轉(zhuǎn)換成Class對(duì)象。 11、如果沒有原始字節(jié),然后調(diào)用findSystemClass查看是否從本地文件系統(tǒng)獲取類。 12、如果resolve參數(shù)是true,那么調(diào)用resolveClass解析Class對(duì)象。 13、如果還沒有類,返回ClassNotFoundException。 14、否則,將類返回給調(diào)用程序。 【tomcat啟動(dòng)類classloader】 t3.tomcat自定義了三個(gè)類,catalinaLoader commonLoader,sharedLoader Common - 載入$CATALINA_HOME/common/...它們對(duì)TOMCAT和所有的WEB APP都可見 Catalina - 載入$CATALINA_HOME/server/..它們僅對(duì)TOMCAT可見,對(duì)所有的WEB APP都不可見 Shared-載入$CATALINA_HOME/shared/它們僅對(duì)所有WEB APP可見,對(duì)TOMCAT不可見(也不必見) t4.Bootstrap通過反射初始化Catalina類, 反射調(diào)用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和幾個(gè)Rule,并且自己實(shí)現(xiàn)了一些 Rule 來(lái)解析xml. 2.tomcat解析xml創(chuàng)建以下幾個(gè)類 Server: org.apache.catalina.core.StandardServer Resources: org.apache.catalina.deploy.NamingResources Server's Listener:( 監(jiān)聽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啟動(dòng)StandardService,StandardService啟動(dòng)Connector, Connector啟動(dòng)Http11Protocol,Http11Protocol啟動(dòng)JIoEndpoint, JioEndpoint啟動(dòng)server Socket,listern 8080端口,處理http請(qǐng)求 4.Http11Processor Processes HTTP requests. 由http11ConnectionHandler調(diào)用,Http11ConnectionHandler由JioEndpoint中的Work 調(diào)用 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模式在各層容器間傳遞請(qǐng)求,將請(qǐng)求通過管道依次通過Engine,Host,Context和 Wrapper。另外,每一個(gè)容器 都可以設(shè)置一系列的Valve去對(duì)請(qǐng)求進(jìn)行攔 截,就像管道中的閥一樣對(duì)請(qǐng)求的行為進(jìn)行一些干涉。 2010-3-31 【tomcat-流程】 1.tomcat的pipeline/valve是標(biāo)準(zhǔn)的責(zé)任鏈模式,每個(gè)級(jí)別的容器中pipeline所有的valve都完成動(dòng)作后會(huì)將 request/response傳到下一個(gè)容器的pipeline中的valve, 這樣一直傳遞下去直到Wrapper的BaseValve. Ps:每個(gè)容器的BaseValve會(huì)調(diào)用下個(gè)容器的起始valve 2.StandardEngine 屬性Pipeline pipeline = new StandardPipeline(this); 構(gòu)造函數(shù)里會(huì)設(shè)置最底層的閥門 pipeline.setBasic(new StandardEngineValve()); 如果需要設(shè)置新閥門處理需求,只需要調(diào)用 pipeline.addValve(Valve valve); 3.CoyoteAdapter中會(huì)執(zhí)行 connector.getContainer().getPipeline().getFirst().invoke(request, response); 該行代碼會(huì)一層一層調(diào)用添加的閥門,處理下去. 2010-4-1 【tomcat-流程】 1.jk插件負(fù)責(zé)tomcat和其它http容器進(jìn)行通信 2.連接器協(xié)議AJP/1.3是tomcat用來(lái)與其它http容器進(jìn)行連接的協(xié)議 3.把指定Context的classloader付給當(dāng)前線程。 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); } 連接器線程調(diào)用worker類的assign類,worker類的執(zhí)行線程run方法會(huì)調(diào)用await方法獲取socket,通過 available變量的設(shè)置和wait/notify方法來(lái)協(xié)調(diào)彼此的操作。當(dāng)連接器線程未傳輸socket,worker類線程就執(zhí)行wait等待, 當(dāng)worker類執(zhí)行線程在處理忙的時(shí)候,連接器線程wait。
|
|
|