小小程序員

          小小程序員
          隨筆 - 5, 文章 - 0, 評(píng)論 - 0, 引用 - 0
          數(shù)據(jù)加載中……

          [源碼學(xué)習(xí)]Tomcat6 源碼學(xué)習(xí)

          Tomcat6 源碼學(xué)習(xí)
          2010-3-29
          【tomcat啟動(dòng)類(lèi)Bootstrap】
          t1.tomcat的人口函數(shù),啟動(dòng)類(lèi)
          org.apache.catalina.startup. Bootstrap.java   Main函數(shù)

          t2.Bootstrap類(lèi)
          初始化 ClassLoader, 然后利用 Java Reflection 調(diào)用 Catalina 類(lèi)來(lái)啟動(dòng) tomcat server

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

          a2.只在本類(lèi)中使用的方法,使用private,降低訪(fǎng)問(wèn)權(quán)限,需要的時(shí)候,再考慮重構(gòu)或者提高訪(fǎng)問(wèn)權(quán)限public

          a.日志打印前加if(log.isInfoEnabled())
          如果代碼中含有l(wèi)ogger.debug(“string”);此類(lèi)語(yǔ)句,盡管在log4j.xml配置文件中對(duì)該類(lèi)logger的level為 ERROR,但是仍然會(huì)產(chǎn)生較大的內(nèi)存開(kāi)銷(xiāo),通常是所要輸出的string的幾十倍甚至上百倍大小,對(duì)內(nèi)存開(kāi)銷(xiāo)非常大。優(yōu)化方法為:使用logger進(jìn)行 判斷。


          2010-3-30
          【tomcat擴(kuò)展-classloader】
          a3.如果兩個(gè)類(lèi)屬于同一個(gè)包下,但是由不同的classloader加載,那么他們也不能互訪(fǎng)default類(lèi)型方法,屬性

          a4.classloader:與C或C++編寫(xiě)的程序不同,Java程序并不是一個(gè)可執(zhí)行文件,而是由許多獨(dú)立的類(lèi)文件組成,每一個(gè)文件基本上 對(duì)應(yīng)于一個(gè)類(lèi)。此外,這些類(lèi)文件并非立即全部都裝入內(nèi)存,而是根據(jù)程序需要裝入內(nèi)存。ClassLoader是JVM中將類(lèi)裝入內(nèi)存的那部分

          a5.定制的ClassLoader應(yīng)用:
          1.在執(zhí)行非置信代碼之前,自動(dòng)驗(yàn)證數(shù)字簽名
          2.使用用戶(hù)提供的密碼透明地解密代碼
          3.動(dòng)態(tài)地創(chuàng)建符合用戶(hù)特定需要的定制化構(gòu)建類(lèi)
          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è)類(lèi)時(shí),先查看它是否在磁盤(pán)的當(dāng)前目錄或相應(yīng)的子目錄。
          2、如果該類(lèi)不存在,但源碼中有,那么調(diào)用Java編譯器來(lái)生成類(lèi)文件。
          3、如果該類(lèi)已存在,檢查它是否比源碼舊。如果是,調(diào)用Java編譯器來(lái)重新生成類(lèi)文件。
          4、如果編譯失敗,或者由于其它原因不能從現(xiàn)有的源碼中生成類(lèi)文件,返回ClassNotFoundException。
          5、如果仍然沒(méi)有該類(lèi),也許它在其它庫(kù)中,所以調(diào)用findSystemClass來(lái)尋找該類(lèi)。
          6、如果還是沒(méi)有,則返回ClassNotFoundException。
          7、否則,返回該類(lèi)。
          8、調(diào)用findLoadedClass來(lái)查看是否存在已裝入的類(lèi)。
          9、如果沒(méi)有,那么采用那種特殊的神奇方式來(lái)獲取原始字節(jié)。
          10、如果已有原始字節(jié),調(diào)用defineClass將它們轉(zhuǎn)換成Class對(duì)象。
          11、如果沒(méi)有原始字節(jié),然后調(diào)用findSystemClass查看是否從本地文件系統(tǒng)獲取類(lèi)。
          12、如果resolve參數(shù)是true,那么調(diào)用resolveClass解析Class對(duì)象。
          13、如果還沒(méi)有類(lèi),返回ClassNotFoundException。
          14、否則,將類(lèi)返回給調(diào)用程序。

          【tomcat啟動(dòng)類(lèi)classloader】
          t3.tomcat自定義了三個(gè)類(lèi),catalinaLoader commonLoader,sharedLoader
          Common - 載入$CATALINA_HOME/common/...它們對(duì)TOMCAT和所有的WEB APP都可見(jiàn)
          Catalina - 載入$CATALINA_HOME/server/..它們僅對(duì)TOMCAT可見(jiàn),對(duì)所有的WEB APP都不可見(jiàn)
          Shared-載入$CATALINA_HOME/shared/它們僅對(duì)所有WEB APP可見(jiàn),對(duì)TOMCAT不可見(jiàn)(也不必見(jiàn))

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


          【tomcat-xml解析】
          1.Tomcat取了Digester中的interface和幾個(gè)Rule,并且自己實(shí)現(xiàn)了一些 Rule 來(lái)解析xml.
          2.tomcat解析xml創(chuàng)建以下幾個(gè)類(lèi)
          Server:
          org.apache.catalina.core.StandardServer
          Resources:
          org.apache.catalina.deploy.NamingResources
          Server's Listener:( 監(jiān)聽(tīng)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通過(guò)protocolHandler(Http11Protocol)傳給Http11Processor,
          Http11Processor解析,create request和response,通過(guò)adapter傳送給Container

          7.Tomcat使用Pipeline模式在各層容器間傳遞請(qǐng)求,將請(qǐng)求通過(guò)管道依次通過(guò)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è)置最底層的閥門(mén)
          pipeline.setBasic(new StandardEngineValve());
          如果需要設(shè)置新閥門(mén)處理需求,只需要調(diào)用 pipeline.addValve(Valve valve);

          3.CoyoteAdapter中會(huì)執(zhí)行
          connector.getContainer().getPipeline().getFirst().invoke(request, response);
          該行代碼會(huì)一層一層調(diào)用添加的閥門(mén),處理下去.

          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)前線(xiàn)程。
          Thread.currentThread().setContextClassLoader(context.getLoader().getClassLoader()); 這樣request就只看見(jiàn)指定的context下面的classes和jar包,而看不見(jiàn)tomcat本身的類(lèi)。

          2010-4-7
          【tomcat-socke與worker線(xiàn)程】
          /**
          * 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);
          }
          連接器線(xiàn)程調(diào)用worker類(lèi)的assign類(lèi),worker類(lèi)的執(zhí)行線(xiàn)程run方法會(huì)調(diào)用await方法獲取socket,通過(guò) available變量的設(shè)置和wait/notify方法來(lái)協(xié)調(diào)彼此的操作。當(dāng)連接器線(xiàn)程未傳輸socket,worker類(lèi)線(xiàn)程就執(zhí)行wait等待,
          當(dāng)worker類(lèi)執(zhí)行線(xiàn)程在處理忙的時(shí)候,連接器線(xiàn)程wait。

          posted on 2010-06-21 10:28 余堅(jiān) 閱讀(840) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): 源碼學(xué)習(xí)


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 垣曲县| 柳江县| 扎兰屯市| 建宁县| 驻马店市| 余江县| 荃湾区| 平昌县| 天祝| 湖口县| 环江| 二连浩特市| 朝阳区| 德惠市| 获嘉县| SHOW| 东乡| 新源县| 天峻县| 桑日县| 舞阳县| 汕头市| 安溪县| 台中县| 屏山县| 灵宝市| 平谷区| 濮阳市| 焉耆| 定安县| 开化县| 改则县| 体育| 西昌市| 兴隆县| 肥城市| 游戏| 斗六市| 高邑县| 太湖县| 叙永县|