乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Tomcat源碼分析

       燮羽 2010-12-02

      1.Tomcat共有五類ClassLoader: 
        commonLoader: 
            用于加載公共jar包,比如servlet規(guī)范包,servlet-api.jar,位于/common 
        catalinaLoader: 
            用于加載Tomcat的實(shí)現(xiàn)jar包,比如catalina.jar,位于/server 
        sharedLoader: 
            用于加載所有應(yīng)用的共享jar包,比如struts核心包就可以放在下面,位于/shared 
        webappClassLoader 
            用于加載web應(yīng)用下的class,一個(gè)web應(yīng)用有一個(gè)webappClassLoader 
        JasperLoader 
            用于加載web應(yīng)用下由jsp編譯后的servlet,一個(gè)web應(yīng)用有一個(gè)JasperLoader 

      它們的父子代理關(guān)系如下: 

                           JREClassLoader 
                                     | 
                           commonLoader 
                           /                       \  
                catalinaLoader        sharedLoader   
                                                    /                      \ 
                                webappClassLoader ........webappClassLoader 
                                           |                                         | 
                                 JasperLoader                   JasperLoader 

      2.WebAppClassLoader加載策略 
        1.首先判斷class是否已經(jīng)加載,若已加載,則直接返回,若沒加載,則進(jìn)行第2步 
        2.使用系統(tǒng)加載器加載class,若加載成功,則返回,若失敗,則進(jìn)行第3步 
        3.如果webAppClassLoader設(shè)置了代理模式,則用父加載器進(jìn)行加載;否則直接加載 
        4.如果webAppClassLoader未設(shè)置代理模式,則自己先加載,失敗后再使用父加載器加載 

      WebappClassLoader類loadClass方法

      Java代碼 
      1. public Class loadClass(String name, boolean resolve)  
      2.         throws ClassNotFoundException {  
      3.   
      4.         if (log.isDebugEnabled())  
      5.             log.debug("loadClass(" + name + ", " + resolve + ")");  
      6.         Class clazz = null;  
      7.   
      8.         // Log access to stopped classloader  
      9.         if (!started) {  
      10.             try {  
      11.                 throw new IllegalStateException();  
      12.             } catch (IllegalStateException e) {  
      13.                 log.info(sm.getString("webappClassLoader.stopped", name), e);  
      14.             }  
      15.         }  
      16.   
      17.         // (0) Check our previously loaded local class cache  
      18.         clazz = findLoadedClass0(name);  
      19.         if (clazz != null) {  
      20.             if (log.isDebugEnabled())  
      21.                 log.debug("  Returning class from cache");  
      22.             if (resolve)  
      23.                 resolveClass(clazz);  
      24.             return (clazz);  
      25.         }  
      26.   
      27.         // (0.1) Check our previously loaded class cache  
      28.         clazz = findLoadedClass(name);  
      29.         if (clazz != null) {  
      30.             if (log.isDebugEnabled())  
      31.                 log.debug("  Returning class from cache");  
      32.             if (resolve)  
      33.                 resolveClass(clazz);  
      34.             return (clazz);  
      35.         }  
      36.   
      37.         // (0.2) Try loading the class with the system class loader, to prevent  
      38.         //       the webapp from overriding J2SE classes  
      39.         try {  
      40.             clazz = system.loadClass(name);  
      41.             if (clazz != null) {  
      42.                 if (resolve)  
      43.                     resolveClass(clazz);  
      44.                 return (clazz);  
      45.             }  
      46.         } catch (ClassNotFoundException e) {  
      47.             // Ignore  
      48.         }  
      49.   
      50.         // (0.5) Permission to access this class when using a SecurityManager  
      51.         if (securityManager != null) {  
      52.             int i = name.lastIndexOf('.');  
      53.             if (i >= 0) {  
      54.                 try {  
      55.                     securityManager.checkPackageAccess(name.substring(0,i));  
      56.                 } catch (SecurityException se) {  
      57.                     String error = "Security Violation, attempt to use " +  
      58.                         "Restricted Class: " + name;  
      59.                     log.info(error, se);  
      60.                     throw new ClassNotFoundException(error, se);  
      61.                 }  
      62.             }  
      63.         }  
      64.   
      65.         boolean delegateLoad = delegate || filter(name);  
      66.   
      67.         // (1) Delegate to our parent if requested  
      68.         if (delegateLoad) {  
      69.             if (log.isDebugEnabled())  
      70.                 log.debug("  Delegating to parent classloader1 " + parent);  
      71.             ClassLoader loader = parent;  
      72.             if (loader == null)  
      73.                 loader = system;  
      74.             try {  
      75.                 clazz = loader.loadClass(name);  
      76.                 if (clazz != null) {  
      77.                     if (log.isDebugEnabled())  
      78.                         log.debug("  Loading class from parent");  
      79.                     if (resolve)  
      80.                         resolveClass(clazz);  
      81.                     return (clazz);  
      82.                 }  
      83.             } catch (ClassNotFoundException e) {  
      84.                 ;  
      85.             }  
      86.         }  
      87.   
      88.         // (2) Search local repositories  
      89.         if (log.isDebugEnabled())  
      90.             log.debug("  Searching local repositories");  
      91.         try {  
      92.             clazz = findClass(name);  
      93.             if (clazz != null) {  
      94.                 if (log.isDebugEnabled())  
      95.                     log.debug("  Loading class from local repository");  
      96.                 if (resolve)  
      97.                     resolveClass(clazz);  
      98.                 return (clazz);  
      99.             }  
      100.         } catch (ClassNotFoundException e) {  
      101.             ;  
      102.         }  
      103.   
      104.         // (3) Delegate to parent unconditionally  
      105.         if (!delegateLoad) {  
      106.             if (log.isDebugEnabled())  
      107.                 log.debug("  Delegating to parent classloader at end: " + parent);  
      108.             ClassLoader loader = parent;  
      109.             if (loader == null)  
      110.                 loader = system;  
      111.             try {  
      112.                 clazz = loader.loadClass(name);  
      113.                 if (clazz != null) {  
      114.                     if (log.isDebugEnabled())  
      115.                         log.debug("  Loading class from parent");  
      116.                     if (resolve)  
      117.                         resolveClass(clazz);  
      118.                     return (clazz);  
      119.                 }  
      120.             } catch (ClassNotFoundException e) {  
      121.                 ;  
      122.             }  
      123.         }  
      124.   
      125.         throw new ClassNotFoundException(name);  
      126.     }  
       
       
      Tomcat的過濾器主要由Filter、FilterChain組成,F(xiàn)ilterChain包含一個(gè)Filter數(shù)組.當(dāng)Wrapper執(zhí)行FilterChain的doFilter(request,response)方法時(shí),F(xiàn)ilterChain首先調(diào)用第一個(gè)Filter的doFilter(request,response,filterchain)方法,當(dāng)?shù)谝粋€(gè)filter做完過濾操作后,它又會(huì)調(diào)用filterchain的doFilter方法,此時(shí)filterchain的當(dāng)前filter已變?yōu)榈诙€(gè)filter,第二個(gè)filter又執(zhí)行dofilter方法,依此類推,直至所有過濾器都執(zhí)行完畢 

      1.接口 
      Java代碼 
      1. public interface Filter {  
      2.         .....         
      3.         //執(zhí)行過濾  
      4.         public void doFilter ( ServletRequest request, ServletResponse response, FilterChain chain ) throws IOException, ServletException;  
      5.   
      6. }  
      7.   
      8. public interface FilterChain {  
      9.     public void doFilter ( ServletRequest request, ServletResponse response ) throws IOException, ServletException;  
      10. }  


      2.實(shí)現(xiàn)例子 
      Java代碼 
      1. class ApplicationFilterChain implements FilterChain {  
      2.      
      3.    //pos為當(dāng)前filter的所在位置,n為filters數(shù)組的長度  
      4.    if (pos < n) {  
      5.             //pos++執(zhí)行后,把filterchain的當(dāng)前filter指向下一個(gè)  
      6.             ApplicationFilterConfig filterConfig = filters[pos++];  
      7.             Filter filter = null;  
      8.             try {  
      9.                 filter = filterConfig.getFilter();  
      10.   
      11.                 //filter執(zhí)行過濾操作  
      12.                 filter.doFilter(request, response, this);  
      13.             }  
      14.             ...  
      15.    }  
      16. }  
      17.   
      18.   
      19. class SampleFilter implements Filter {  
      20.       ........  
      21.       public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain)  
      22.         throws IOException, ServletException {  
      23.            
      24.          //do something   
      25.          .....  
      26.          //request, response傳遞給下一個(gè)過濾器進(jìn)行過濾  
      27.          chain.doFilter(request, response);  
      28.     }  
      29.         
      30. }  


      過濾器可以在web.xml中進(jìn)行配置
       

      Tomcat源碼分析(閥門)

      關(guān)鍵字: tomcat源碼分析
      1.Tomcat組件及關(guān)系 

      Server 
         --Service 
              --Connector 
              --Engine 
                  --Host 
                       --Context 
                           --Wrapper(Servlet) 

      Server代表Tomcat應(yīng)用服務(wù)器,它可以包含多個(gè)Service服務(wù);一個(gè)Service服務(wù)包含多個(gè)Connector和一個(gè)Engine;一個(gè)Engine可以包含多個(gè)虛擬主機(jī)Host;一個(gè)Host可以包含多個(gè)Web應(yīng)用Context,而每個(gè)Web下有可以包含多個(gè)Wrapper(Servlet的包裝器) 
      組件及其關(guān)系可以參考Tomcat的Server.xml及Web.xml文件 


      2.當(dāng)一個(gè)請(qǐng)求到達(dá)時(shí),Connector會(huì)把它包裝成Request對(duì)象,同時(shí)生成Response對(duì)象;然后Connector會(huì)調(diào)用Engine的invoke方法,它又會(huì)調(diào)用Host的invoke 方法,Host的invoke方法又會(huì)調(diào)用Context的invoke方法,最后,Context的invoke方法調(diào)用Wrapper的invoke方法,至此,責(zé)任鏈調(diào)用結(jié)束。 


      接口及實(shí)現(xiàn): 
      a.Pipeline , 此接口的實(shí)現(xiàn)主要用于維護(hù)閥門及先后關(guān)系,實(shí)現(xiàn)見  org.apache.catalina.core.StandardPipleline 
      Java代碼 
      1. public interface Pipeline {  
      2.      
      3.    //獲取最后一個(gè)閥門   
      4.    public Valve getBasic();  
      5.      
      6.    //設(shè)置最后一個(gè)閥門  
      7.    public void setBasic(Valve valve);  
      8.   
      9.    //添加閥門  
      10.    public void addValve(Valve valve);  
      11.   
      12.    public Valve[] getValves();  
      13.   
      14.    public void removeValve(Valve valve);  
      15.   
      16.    //獲取第一個(gè)閥門  
      17.    public Valve getFirst();  
      18.   
      19.     


      b.Valve , 閥門接口,主要用于做過濾工作 
      Java代碼 
      1.   public interface Valve {  
      2.   
      3.     public String getInfo();  
      4.   
      5.     //獲取下一個(gè)閥門  
      6.     public Valve getNext();  
      7.   
      8.     //設(shè)置下一個(gè)閥門  
      9.     public void setNext(Valve valve);  
      10.   
      11.     public void backgroundProcess();  
      12.   
      13.     //閥門過濾  
      14.     public void invoke(Request request, Response response)  
      15.         throws IOException, ServletException;  
      16.   
      17. }  


      c.下面是與責(zé)任鏈有關(guān)的實(shí)現(xiàn)代碼,以Engine的標(biāo)準(zhǔn)實(shí)現(xiàn)StandardEngine為例 
      Java代碼 
      1. StandardEngine{  
      2.       
      3.     public StandardEngine() {  
      4.         super();  
      5.         //設(shè)置StandardEngineValve為Engine的最后一個(gè)閥門  
      6.         pipeline.setBasic(new StandardEngineValve());   
      7.     }  
      8.       
      9.    //添加閥門  
      10.     public synchronized void addValve(Valve valve) {  
      11.         pipeline.addValve(valve);  
      12.     }  
      13.   
      14.     //此方法被Connector調(diào)用  
      15.     public void invoke(Request request, Response response)  
      16.         throws IOException, ServletException {  
      17.         pipeline.getFirst().invoke(request, response);  
      18.     }  
      19. }  

         
      d.StandardEngine簡單閥門的實(shí)現(xiàn) 
      Java代碼 
      1. SimpleValve implements Valve{  
      2.    ....  
      3.    //閥門過濾方法  
      4.     public void invoke(Request request, Response response)  
      5.         throws IOException, ServletException{  
      6.        //do something  
      7.        //調(diào)用下一個(gè)閥門的invoke方法  
      8.        getNext().invoke(Request request, Response response);  
      9.        //do something  
      10.    }  
      11. }  


      e.StandardEngine最后一個(gè)閥門(StandardEngineValve)的實(shí)現(xiàn) 
      Java代碼 
      1. StandardEngineValve extends ValveBase{  
      2.    ...  
      3.    public void invoke(Request request, Response response)  
      4.         throws IOException, ServletException{  
      5.         Host host = request.getHost();  
      6.           
      7.         //至此,StandardEngine中的閥門都已處理完畢,下面把request、  
      8.          //response對(duì)象交給host處理  
      9.         host.getPipeline().getFirst().invoke(request, response);  
      10. }  


      c,d,e代碼即為StandardEngine責(zé)任鏈調(diào)用的主要代碼,Host、Context、Wrapper的責(zé)任鏈調(diào)用相關(guān)代碼與其類似,閥門可以在Server.xml及Web.xml中配置 

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多