亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

How Tomcat Works(七)

系統 1846 0

本文接下來介紹并分析servlet容器,servlet容器是用來處理請求servlet資源,并為web客戶端填充response對象的模塊。

servlet容器是org.apache.catalina.Container接口的實例,在tomcat中,有四種類型的容器,分別為Engine、Host 、Context和Wrapper。

Engine. 代表整個容器的servlet引擎。
Host.代表一個擁有一定數量Context的虛擬主機。
Context.代表一個Web項目.一個Context包含一個或多個Wrapper。
Wrapper.代表單獨的一個servlet。

這些容器構成一個自頂向下的等級結構,高等級的容器可以具有多個直接下屬等級的容器實例(子容器),這有點類似于composite模式,不過還是有差別的

org.apache.catalina.Container接口聲明如下

      
        //
      
      
        添加
      
      
        public
      
      
        void
      
      
         addChild(Container child);

      
      
        //
      
      
        刪除
      
      
        public
      
      
        void
      
      
         removeChild(Container child);

      
      
        //
      
      
        查找
      
      
        public
      
      
         Container findChild(String name);

      
      
        //
      
      
        查找全部
      
      
        public
      
       Container[] findChildren();
    

上面方法均為操作子容器的相關方法

容器可以包含一些支持的組件,諸如載入器、記錄器、管理器、領域和資源等,我們可以通過編輯server.xml文件來決定使用哪種容器。

下面我們來分析servlet容器是怎么執行任務的,這里就要提到servlet容器的管道模型,管道包含了該servlet容器將要調用的任務,而閥則表示一個具體的執行任務;在servlet容器的管道中,有一個基礎閥,也可以添加任意數量的額外閥,閥的數量通常是指額外添加的閥的數量,不包括基礎閥

這里就好像servlet編程中的過濾器模型,管道好比過濾器鏈,而閥則是具體的過濾器;基礎閥總是最后一個執行的。

這里涉及幾個相關的接口,包括Pipeline、Valve、ValveContext 和Contained

Pipeline接口聲明如下

      
        public
      
      
        interface
      
      
         Pipeline {
   
      
      
        public
      
      
         Valve getBasic();

      
      
        public
      
      
        void
      
      
         setBasic(Valve valve);
    
      
      
        public
      
      
        void
      
      
         addValve(Valve valve);
   
      
      
        public
      
      
         Valve[] getValves();
   
      
      
        public
      
      
        void
      
      
         invoke(Request request, Response response)
        
      
      
        throws
      
      
         IOException, ServletException;
   
      
      
        public
      
      
        void
      
      
         removeValve(Valve valve);

}
      
    

Valve接口聲明如下

      
        public
      
      
        interface
      
      
         Valve {
        
public String getInfo(); public void invoke(Request request, Response response, ValveContext context) throws IOException, ServletException; }

ValveContext接口聲明

      
        public
      
      
        interface
      
      
         ValveContext {
  
      
      
        public
      
      
         String getInfo();
   
      
      
        public
      
      
        void
      
      
         invokeNext(Request request, Response response)
        
      
      
        throws
      
      
         IOException, ServletException;
}
      
    

Contained接口聲明

      
        public
      
      
        interface
      
      
         Contained {
    
      
      
        public
      
      
         Container getContainer();
   
      
      
        public
      
      
        void
      
      
         setContainer(Container container);

}
      
    

閥可以選擇是否實現該接口,設置閥與一個servlet容器相關連

下面我們來學習Wrapper容器,Wrapper容器表示一個獨立的servlet定義,負責管理其基礎servlet類的生命周期,它繼承了Container接口,另外添加了額外方法聲明。其中比較重要的方法聲明是load()方法和allocate()方法,均與載入及初始化servlet類相關(供基礎閥調用,基礎閥持有Wrapper容器實例引用)

下面來分析一個簡單的Wrapper類,該類實現了org.apache.catalina.Wrapper接口和org.apache.catalina.Pipeline接口

      
        public
      
      
        class
      
       SimpleWrapper 
      
        implements
      
      
         Wrapper, Pipeline {

  
      
      
        //
      
      
         the servlet instance
      
      
        private
      
       Servlet instance = 
      
        null
      
      
        ;
  
      
      
        private
      
      
         String servletClass;
  
      
      
        private
      
      
         Loader loader; 
      
      
        private
      
       SimplePipeline pipeline = 
      
        new
      
       SimplePipeline(
      
        this
      
      
        );
  
      
      
        protected
      
       Container parent = 
      
        null
      
      
        ;

  
      
      
        public
      
      
         SimpleWrapper() {
    pipeline.setBasic(
      
      
        new
      
      
         SimpleWrapperValve());
  }

  
      
      
        public
      
      
        synchronized
      
      
        void
      
      
         addValve(Valve valve) {
    pipeline.addValve(valve);
  }

  
      
      
        public
      
       Servlet allocate() 
      
        throws
      
      
         ServletException {
    
      
      
        //
      
      
         Load and initialize our instance if necessary
      
      
        if
      
       (instance==
      
        null
      
      
        ) {
      
      
      
        try
      
      
         {
        instance 
      
      =
      
         loadServlet();
      }
      
      
      
        catch
      
      
         (ServletException e) {
        
      
      
        throw
      
      
         e;
      }
      
      
      
        catch
      
      
         (Throwable e) {
        
      
      
        throw
      
      
        new
      
       ServletException("Cannot allocate a servlet instance"
      
        , e);
      }
    }
    
      
      
        return
      
      
         instance;
  }

  
      
      
        private
      
       Servlet loadServlet() 
      
        throws
      
      
         ServletException {
    
      
      
        if
      
       (instance!=
      
        null
      
      
        )
      
      
      
        return
      
      
         instance;

    Servlet servlet 
      
      = 
      
        null
      
      
        ;
    String actualClass 
      
      =
      
         servletClass;
    
      
      
        if
      
       (actualClass == 
      
        null
      
      
        ) {
      
      
      
        throw
      
      
        new
      
       ServletException("servlet class has not been specified"
      
        );
    }

    Loader loader 
      
      =
      
         getLoader();
    
      
      
        //
      
      
         Acquire an instance of the class loader to be used
      
      
        if
      
       (loader==
      
        null
      
      
        ) {
      
      
      
        throw
      
      
        new
      
       ServletException("No loader."
      
        );
    }
    ClassLoader classLoader 
      
      =
      
         loader.getClassLoader();

    
      
      
        //
      
      
         Load the specified servlet class from the appropriate class loader
      
      
    Class classClass = 
      
        null
      
      
        ;
    
      
      
        try
      
      
         {
      
      
      
        if
      
       (classLoader!=
      
        null
      
      
        ) {
        classClass 
      
      =
      
         classLoader.loadClass(actualClass);
      }
    }
    
      
      
        catch
      
      
         (ClassNotFoundException e) {
      
      
      
        throw
      
      
        new
      
       ServletException("Servlet class not found"
      
        );
    }
    
      
      
        //
      
      
         Instantiate and initialize an instance of the servlet class itself
      
      
        try
      
      
         {
      servlet 
      
      =
      
         (Servlet) classClass.newInstance();
    }
    
      
      
        catch
      
      
         (Throwable e) {
      
      
      
        throw
      
      
        new
      
       ServletException("Failed to instantiate servlet"
      
        );
    }

    
      
      
        //
      
      
         Call the initialization method of this servlet
      
      
        try
      
      
         {
      servlet.init(
      
      
        null
      
      
        );
    }
    
      
      
        catch
      
      
         (Throwable f) {
      
      
      
        throw
      
      
        new
      
       ServletException("Failed initialize servlet."
      
        );
    }
    
      
      
        return
      
      
         servlet;
  }  
      
      
        public
      
      
         Loader getLoader() {
    
      
      
        if
      
       (loader != 
      
        null
      
      
        )
      
      
      
        return
      
      
         (loader);
    
      
      
        if
      
       (parent != 
      
        null
      
      
        )
      
      
      
        return
      
      
         (parent.getLoader());
    
      
      
        return
      
       (
      
        null
      
      
        );
  }
      
      
        public
      
      
        void
      
      
         invoke(Request request, Response response)
    
      
      
        throws
      
      
         IOException, ServletException {
    pipeline.invoke(request, response);
  }  
      
      
        public
      
      
        void
      
       load() 
      
        throws
      
      
         ServletException {
    instance 
      
      =
      
         loadServlet();
  }
        
// method implementations of Pipeline public Valve getBasic() { return pipeline.getBasic(); } public void setBasic(Valve valve) { pipeline.setBasic(valve); } public Valve[] getValves() { return pipeline.getValves(); } public void removeValve(Valve valve) { pipeline.removeValve(valve); } }

上面的SimpleWrapper類由于實現了org.apache.catalina.Pipeline接口接口,同時與該接口相關的實現方法都是調用引用的成員變量SimplePipeline pipeline = new SimplePipeline(this)的對應方法,因此我們可以理解為SimpleWrapper類為SimplePipeline的包裝類

在它的invoke()方法里面調用了成員變量的SimplePipeline pipeline = new SimplePipeline(this)的invoke()方法,這里構造函數傳入SimpleWrapper實例本身,可以猜想是為了獲取其載入器及具體的servlet實現類(注:該方法為Container接口與Pipeline接口都具有的方法聲明,因此SimpleWrapper類只要一個實現),下面我們繼續分析SimplePipeline相關實現

      
        public
      
      
        class
      
       SimplePipeline 
      
        implements
      
      
         Pipeline {

  
      
      
        public
      
      
         SimplePipeline(Container container) {
    setContainer(container);
  }

  
      
      
        //
      
      
         The basic Valve (if any) associated with this Pipeline.
      
      
        protected
      
       Valve basic = 
      
        null
      
      
        ;
  
      
      
        //
      
      
         The Container with which this Pipeline is associated.
      
      
        protected
      
       Container container = 
      
        null
      
      
        ;
  
      
      
        //
      
      
         the array of Valves
      
      
        protected
      
       Valve valves[] = 
      
        new
      
       Valve[0
      
        ];

  
      
      
        public
      
      
        void
      
      
         setContainer(Container container) {
    
      
      
        this
      
      .container =
      
         container;
  }

  
      
      
        public
      
      
         Valve getBasic() {
    
      
      
        return
      
      
         basic;
  }

  
      
      
        public
      
      
        void
      
      
         setBasic(Valve valve) {
    
      
      
        this
      
      .basic =
      
         valve;
    ((Contained) valve).setContainer(container);
  }

  
      
      
        public
      
      
        void
      
      
         addValve(Valve valve) {
    
      
      
        if
      
       (valve 
      
        instanceof
      
      
         Contained)
      ((Contained) valve).setContainer(
      
      
        this
      
      
        .container);

    
      
      
        synchronized
      
      
         (valves) {
      Valve results[] 
      
      = 
      
        new
      
       Valve[valves.length +1
      
        ];
      System.arraycopy(valves, 
      
      0, results, 0
      
        , valves.length);
      results[valves.length] 
      
      =
      
         valve;
      valves 
      
      =
      
         results;
    }
  }

  
      
      
        public
      
      
         Valve[] getValves() {
    
      
      
        return
      
      
         valves;
  }

  
      
      
        public
      
      
        void
      
      
         invoke(Request request, Response response)
    
      
      
        throws
      
      
         IOException, ServletException {
    
      
      
        //
      
      
         Invoke the first Valve in this pipeline for this request
      
      
    (
      
        new
      
      
         SimplePipelineValveContext()).invokeNext(request, response);
  }

  
      
      
        public
      
      
        void
      
      
         removeValve(Valve valve) {
  }

  
      
      
        //
      
      
         this class is copied from org.apache.catalina.core.StandardPipeline class's
  
      
      
        //
      
      
         StandardPipelineValveContext inner class.
      
      
        protected
      
      
        class
      
       SimplePipelineValveContext 
      
        implements
      
      
         ValveContext {

    
      
      
        protected
      
      
        int
      
       stage = 0
      
        ;

    
      
      
        public
      
      
         String getInfo() {
      
      
      
        return
      
      
        null
      
      
        ;
    }

    
      
      
        public
      
      
        void
      
      
         invokeNext(Request request, Response response)
      
      
      
        throws
      
      
         IOException, ServletException {
      
      
      
        int
      
       subscript =
      
         stage;
      stage 
      
      = stage + 1
      
        ;
      
      
      
        //
      
      
         Invoke the requested Valve for the current request thread
      
      
        if
      
       (subscript <
      
         valves.length) {
        valves[subscript].invoke(request, response, 
      
      
        this
      
      
        );
      }
      
      
      
        else
      
      
        if
      
       ((subscript == valves.length) && (basic != 
      
        null
      
      
        )) {
        basic.invoke(request, response, 
      
      
        this
      
      
        );
      }
      
      
      
        else
      
      
         {
        
      
      
        throw
      
      
        new
      
       ServletException("No valve"
      
        );
      }
    }
  } 
      
      
        //
      
      
         end of inner class
      
      
        
}
      
    

invoke()方法里面調用內部類SimplePipelineValveContext(實現了ValveContext接口),遍歷執行各個閥的invoke()方法

wrapper容器執行的基本流程如上所述,下面我們來進一步分析相關輔助類及實現類等

在應用初始化servlet容器時,我們需要為其指定一個載入器,下面是一個簡單的載入器,實現了Loader接口

      
        public
      
      
        class
      
       SimpleLoader 
      
        implements
      
      
         Loader {

  
      
      
        public
      
      
        static
      
      
        final
      
       String WEB_ROOT =
      
        
    System.getProperty(
      
      "user.dir") + File.separator  + "webroot"
      
        ;

  ClassLoader classLoader 
      
      = 
      
        null
      
      
        ;
  Container container 
      
      = 
      
        null
      
      
        ;

  
      
      
        public
      
      
         SimpleLoader() {
    
      
      
        try
      
      
         {
      URL[] urls 
      
      = 
      
        new
      
       URL[1
      
        ];
      URLStreamHandler streamHandler 
      
      = 
      
        null
      
      
        ;
      File classPath 
      
      = 
      
        new
      
      
         File(WEB_ROOT);
      String repository 
      
      = (
      
        new
      
       URL("file", 
      
        null
      
      , classPath.getCanonicalPath() +
      
         File.separator)).toString() ;
      urls[
      
      0] = 
      
        new
      
       URL(
      
        null
      
      
        , repository, streamHandler);
      classLoader 
      
      = 
      
        new
      
      
         URLClassLoader(urls);
    }
    
      
      
        catch
      
      
         (IOException e) {
      System.out.println(e.toString() );
    }


  }

  
      
      
        public
      
      
         ClassLoader getClassLoader() {
    
      
      
        return
      
      
         classLoader;
  }

  
      
      
        public
      
      
         Container getContainer() {
    
      
      
        return
      
      
         container;
  }
   
      
      
        //
      
      
        這里省略其余代碼
      
      
}
    

基礎閥是干嘛的呢,具體來說是調用具體servlet的service()方法(管道持有對基礎閥的引用)

      
        public
      
      
        class
      
       SimpleWrapperValve 
      
        implements
      
      
         Valve, Contained {

  
      
      
        protected
      
      
         Container container;

  
      
      
        public
      
      
        void
      
      
         invoke(Request request, Response response, ValveContext valveContext)
    
      
      
        throws
      
      
         IOException, ServletException {

    SimpleWrapper wrapper 
      
      =
      
         (SimpleWrapper) getContainer();
    ServletRequest sreq 
      
      =
      
         request.getRequest();
    ServletResponse sres 
      
      =
      
         response.getResponse();
    Servlet servlet 
      
      = 
      
        null
      
      
        ;
    HttpServletRequest hreq 
      
      = 
      
        null
      
      
        ;
    
      
      
        if
      
       (sreq 
      
        instanceof
      
      
         HttpServletRequest)
      hreq 
      
      =
      
         (HttpServletRequest) sreq;
    HttpServletResponse hres 
      
      = 
      
        null
      
      
        ;
    
      
      
        if
      
       (sres 
      
        instanceof
      
      
         HttpServletResponse)
      hres 
      
      =
      
         (HttpServletResponse) sres;

    
      
      
        //
      
      
         Allocate a servlet instance to process this request
      
      
        try
      
      
         {
      servlet 
      
      =
      
         wrapper.allocate();
      
      
      
        if
      
       (hres!=
      
        null
      
       && hreq!=
      
        null
      
      
        ) {
        servlet.service(hreq, hres);
      }
      
      
      
        else
      
      
         {
        servlet.service(sreq, sres);
      }
    }
    
      
      
        catch
      
      
         (ServletException e) {
    }
  }

  
      
      
        public
      
      
         String getInfo() {
    
      
      
        return
      
      
        null
      
      
        ;
  }

  
      
      
        public
      
      
         Container getContainer() {
    
      
      
        return
      
      
         container;
  }

  
      
      
        public
      
      
        void
      
      
         setContainer(Container container) {
    
      
      
        this
      
      .container =
      
         container;
  }
}
      
    

其他額外添加的閥本人就不在具體描述了,至此SimpleWrapper容器分析完畢!

---------------------------------------------------------------------------?

本系列How Tomcat Works系本人原創?

轉載請注明出處 博客園 刺猬的溫馴?

本人郵箱: chenying998179 # 163.com ( #改為@

本文鏈接 http://www.cnblogs.com/chenying99/p/3235544.html

How Tomcat Works(七)


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 波多野结衣在线一区二区 | 99久久网| 久久久久久夜精品精品免费 | 美女视频黄视大全视频免费网址 | 国产精品久久久久不卡绿巨人 | 在线亚洲精品国产成人二区 | 日本一区二 | 亚洲欧美日韩综合在线 | 日韩欧美一区二区在线观看 | 久久久久久久久久久福利观看 | 美女一级毛片免费观看 | 99爱在线视频这里只有精品 | 国产精品爱久久 | 五月婷婷社区 | 黄色wwwwww| 日本一级成人毛片免费观看 | 天天色天天做 | 亚洲国产精品综合久久网络 | 国产成人禁片免费观看 | 欧美熟videos肥婆 | 狠狠色婷婷丁香综合久久韩国 | 免费一级毛片在线播放不收费 | 日本视频不卡 | 亚洲五月综合网色九月色 | a久久| 久久国产欧美日韩精品免费 | 99久久久久国产 | 女人十八毛片免费观 | 九九九精品 | 欧美一级视频在线观看欧美 | 九九免费在线视频 | 美女被a到爽视频在线观看 美女被cao的视频免费看 | 国内精品久久久久久影院8f | 精品免费国产一区二区女 | 天天操人人 | 国产九九免费视频网站 | 中文字幕在线观看免费视频 | 99精品在线免费 | 一级毛片在线 | 中文字幕专区在线亚洲 | 久久艹国产|