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

查看tomcat啟動文件都干點啥---server對象

系統 2039 0

? ? ?在上一章 查看tomcat啟動文件都干點啥---Catalina.java 中說道了構造Server,,這次嘗試著說一下Tomcat中Server的內容,首先看一下org.apache.catalina.Server接口中定義的方法:

查看tomcat啟動文件都干點啥---server對象

  從這里至少可以看出Server中包含很多Service,通過實現如下接口添加一個新的Service到Services的集合中,或者從集合中刪除指定的Service: ?

      
        public
      
      
        void
      
      
         addService(Service service);


      
      
        public
      
      
        void
      
       removeService(Service service);
    

  通過實現如下接口來完成通過service的名稱返回Service的操作:  

      
        public
      
       Service findService(String name);
    

  通過實現如下接口來完成獲取返回Server中所有Service的操作:  

      
        public
      
       Service[] findServices();
    

  對于Server的網絡內容的設置和獲取通過如下方法,包括設置地址,端口:  

      
        public
      
      
        int
      
      
         getPort();


      
      
        public
      
      
        void
      
       setPort(
      
        int
      
      
         port);


      
      
        public
      
      
         String getAddress();


      
      
        public
      
      
        void
      
       setAddress(String address);
    

  獲取和指定shotdown命令:

      
        public
      
      
         String getShutdown();


      
      
        public
      
      
        void
      
       setShutdown(String shutdown);
    

  獲取和設置父類的加載器:  

      
        public
      
      
         ClassLoader getParentClassLoader();


      
      
        public
      
      
        void
      
       setParentClassLoader(ClassLoader parent);
    

  如果設置了Catalina,那么也提供獲取和設置的方法:  

      
        public
      
      
         Catalina getCatalina();


      
      
        public
      
      
        void
      
       setCatalina(Catalina catalina);
    

  通過Server接口至少我們能夠得出結論:Server中包含多個Service對象。

  結構如下:

查看tomcat啟動文件都干點啥---server對象

  值得注意的是Server借口繼承了Lifecycle接口,

      
        public
      
      
        interface
      
       Server 
      
        extends
      
       Lifecycle 
    

  Lifecycle 接口就是來控制Server極其組件的生命周期的,組件實現Lifecycle借口,就可以提供一致化的機制來啟動和停止組件。下面看一下?Lifecycle的內容:

  首先是一些常量列表,小插曲,在Tomcat7.0.53中,tomcat在此處的注釋有小問題,有興趣的人可以看一下。  

      
        //
      
      
        組件初始化之前的事件
      
      
        public
      
      
        static
      
      
        final
      
       String BEFORE_INIT_EVENT = "before_init"
      
        ;

   
      
      
        //
      
      
        組件初始化之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String AFTER_INIT_EVENT = "after_init"
      
        ;

   
      
      
        //
      
      
        組件start的事件
      
      
        public
      
      
        static
      
      
        final
      
       String START_EVENT = "start"
      
        ;

   
      
      
        //
      
      
        組件start之前的事件
      
      
        public
      
      
        static
      
      
        final
      
       String BEFORE_START_EVENT = "before_start"
      
        ;

   
      
      
        //
      
      
        組件start之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String AFTER_START_EVENT = "after_start"
      
        ;

   
      
      
        //
      
      
        組件stop之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String STOP_EVENT = "stop"
      
        ;

   
      
      
        //
      
      
        組件stop之前的事件
      
      
        public
      
      
        static
      
      
        final
      
       String BEFORE_STOP_EVENT = "before_stop"
      
        ;

   
      
      
        //
      
      
        組件stop之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String AFTER_STOP_EVENT = "after_stop"
      
        ;

   
      
      
        //
      
      
        組件destrop之后的事件
      
      
        public
      
      
        static
      
      
        final
      
       String AFTER_DESTROY_EVENT = "after_destroy"
      
        ;

   
      
      
        //
      
      
        組件destrop之前的事件
      
      
        public
      
      
        static
      
      
        final
      
       String BEFORE_DESTROY_EVENT = "before_destroy"
      
        ;

    
      
      
        //
      
      
        組件periodic的事件 
      
      
        public
      
      
        static
      
      
        final
      
       String PERIODIC_EVENT = "periodic";
    

  下面就是Lifecycle接口定義的方法列表:

查看tomcat啟動文件都干點啥---server對象

  既然Server中包含的主要對象就是Service,實現了Service就是對外提供服務了,下面在看一下Service的接口定義:

查看tomcat啟動文件都干點啥---server對象

  看了定義的方法之后,很想逐一說明一下,可能會發現問題:

  在Service中添加或移除connector的方法:    

      
        public
      
      
        void
      
      
         addConnector(Connector connector);


      
      
        public
      
      
        void
      
       removeConnector(Connector connector);
    

? ? 說明在每個Service中有多個Connector。

  在Service中添加或移除Executor的方法:   

      
        public
      
      
        void
      
      
         addExecutor(Executor ex);


      
      
        public
      
      
        void
      
       removeExecutor(Executor ex);
    

  返回所有Connector的方法:

      
        public
      
       Connector[] findConnectors();
    

  返回所有executor的方法:  

      
        public
      
       Executor[] findExecutors();
    

  設置和獲取Container的方法:  

      
        public
      
      
         Container getContainer();


      
      
        public
      
      
        void
      
       setContainer(Container container);
    

  獲取和設置關聯的Server對象的方法:  

      
        public
      
      
        void
      
      
         setServer(Server server);


      
      
        public
      
       Server getServer();
    

  給Service設置獲取名稱的方法:  

      
        public
      
      
        void
      
      
         setName(String name);


      
      
        public
      
       String getName();
    

  以上就是Service接口定義的主要方法,得出在Service中包含一個或多個Connector,包含一個或多個Executors和一個Container對象。接著上面的Server---Service圖我們可以得出如下關系圖: ? ? ? ? ? ? ? ? ? ? ?

            |---------Connector 

 Server----Service----|

            ?|----------Container

查看tomcat啟動文件都干點啥---server對象

  由此可知在Tomcat中的兩個重要的組件就是Connector和Container。下面我們著重看一下Connector和Container。

  Container的主要功能是執行從客戶端接收的請求,然后給出回應。看一下Container接口定義的方法:

  添加,刪除和獲取一個子Container:  

      
        public
      
      
        void
      
      
         addChild(Container child);


      
      
        public
      
      
        void
      
      
         removeChild(Container child);


      
      
        public
      
      
         Container findChild(String name);


      
      
        public
      
       Container[] findChildren();
    

  對應的在Container中就應該有設置和獲取父Container的方法:  

      
        public
      
      
        void
      
      
         setParent(Container container);


      
      
        public
      
       Container getParent();
    

  在Container中添加,移除和獲取事件監聽器:

      
        public
      
      
        void
      
      
         addContainerListener(ContainerListener listener);


      
      
        public
      
      
        void
      
      
         removeContainerListener(ContainerListener listener);


      
      
        public
      
       ContainerListener[] findContainerListeners();
    

  在Container中添加,移除和獲取屬性變更監聽器:  

      
        public
      
      
        void
      
      
         addPropertyChangeListener(PropertyChangeListener listener);


      
      
        public
      
      
        void
      
       removePropertyChangeListener(PropertyChangeListener listener);
    

  觸發Container事件:

      
        public
      
      
        void
      
       fireContainerEvent(String type, Object data);
    

  記錄指向這個container的請求與響應的日志:  

      
        public
      
       AccessLog getAccessLog();
    

  設置和獲取作用在該container及其子container上的方法的延遲時間,單位秒:  

      
        public
      
      
        void
      
       setBackgroundProcessorDelay(
      
        int
      
      
         delay);


      
      
        public
      
      
        int
      
       getBackgroundProcessorDelay();
    

  設置和獲取相關的集群:  

      
        public
      
      
        void
      
      
         setCluster(Cluster cluster);


      
      
        public
      
       Cluster getCluster();
    

  設置和獲取Loadeer:  

      
        public
      
      
        void
      
      
         setLoader(Loader loader);


      
      
        public
      
       Loader getLoader();
    

  設置和獲取負責管理該Container對應Session pool的Manager對象:  

      
        public
      
      
        void
      
      
         setManager(Manager manager);


      
      
        public
      
       Manager getManager();
    

  設置和獲取Container的名字描述:  

      
        public
      
      
        void
      
      
         setName(String name);


      
      
        public
      
       String getName();
    

  設置和獲取父類的ClassLoader:  

      
        public
      
      
        void
      
      
         setParentClassLoader(ClassLoader parent);


      
      
        public
      
       ClassLoader getParentClassLoader();
    

  獲取Pipeline,負責管理該Container中的相關值:  

      
        public
      
       Pipeline getPipeline();
    

  設置和獲取Container的上下文資源:  

      
        public
      
      
        void
      
      
         setResources(DirContext resources);


      
      
        public
      
       DirContext getResources();
    

  設置和獲取啟動和停止children container的線程數,可以并行的啟動和停止子container:  

      
        public
      
      
        void
      
       setStartStopThreads(
      
        int
      
      
         startStopThreads);


      
      
        public
      
      
        int
      
       getStartStopThreads();
    

  Connector類中的變量已經方法實現如下:

  代表一個Container的入口的變量:  

      
        protected
      
       Adapter adapter = 
      
        null
      
      ;
    

  實現Servlet的API規則匹配的變量:  

      
        protected
      
       Mapper mapper = 
      
        new
      
       Mapper();
    

  是否允許Trace:  

      
        protected
      
      
        boolean
      
       allowTrace = 
      
        false
      
      ;
    

  異步請求的超時時間:  

      
        protected
      
      
        long
      
       asyncTimeout = 10000;
    

  是否允許DNS查找的標記:  

      
        protected
      
      
        boolean
      
       enableLookups = 
      
        false
      
      ;
    

  Mapper監聽器:  

      
        protected
      
       MapperListener mapperListener = 
      
        new
      
       MapperListener(mapper, 
      
        this
      
      );
    

  GET和POST方法中,Container解析的最大的參數個數限制(默認值為1000,當設置數值小于0時,表示沒有限制):  

      
        protected
      
      
        int
      
       maxParameterCount = 10000;
    

  Container接收POST方法傳遞的最大數據(默認值為2M):  

      
        protected
      
      
        int
      
       maxPostSize = 2 * 1024 * 1024;
    

  在Container認證時候默認保存的最大數據:(默認值4K):  

      
          protected
      
      
        int
      
       maxSavePostSize = 4 * 1024;
    

  一系列以逗號分割的,application/x-www-form-urlencoded形式的方法請求體,以什么方式轉化成方法的集合:  

      
        protected
      
       String parseBodyMethods = "POST";
    

  通過parseBodyMethods方式確定的方法集合:  

      
        protected
      
       HashSet<String> parseBodyMethodsSet;
    

  監聽請求端口的數量:(默認值為-1):  

      
        protected
      
      
        int
      
       port = -1;
    

  connector對象將請求重定向到那個Server:  

      
          protected
      
       String proxyName = 
      
        null
      
      ;
    

  connector對象請求重定向到server的哪個端口:  

      
        protected
      
      
        int
      
       proxyPort = 0;
    

?  從no-ssl到ssl重定向端口:  

      
        protected
      
      
        int
      
       redirectPort = 443;
    

  通過connector接收到的所有請求的請求方案:  

      
          protected
      
       String scheme = "http";
    

  是否給每個接收到的請求設置安全連接標記:  

      
        protected
      
      
        boolean
      
       secure = 
      
        false
      
      ;
    

  一個String幫助對象:  

      
        protected
      
      
        static
      
      
        final
      
       StringManager sm =
      
         StringManager.getManager(Constants.Package);
      
    

  關聯的Service對象:  

      
        protected
      
       Service service = 
      
        null
      
      ;
    

  URL編碼:  

      
        protected
      
       String URIEncoding = 
      
        null
      
      ;
    

  是否用body編碼給URL編碼:(不明白)  

      
        protected
      
      
        boolean
      
       useBodyEncodingForURI = 
      
        false
      
      ;
    

  是否用IP綁定虛擬主機:  

      
        protected
      
      
        boolean
      
       useIPVHosts = 
      
        false
      
      ;
    

  下面看一下Connector的構造函數:

      
          public
      
      
         Connector() {

        
      
      
        this
      
      (
      
        null
      
      
        );

    }



    
      
      
        public
      
      
         Connector(String protocol) {

        setProtocol(protocol);

        
      
      
        //
      
      
         Instantiate protocol handler
      
      
        try
      
      
         {

            Class
      
      <?> clazz =
      
         Class.forName(protocolHandlerClassName);

            
      
      
        this
      
      .protocolHandler =
      
         (ProtocolHandler) clazz.newInstance();

        } 
      
      
        catch
      
      
         (Exception e) {

            log.error(sm.getString(

                    
      
      "coyoteConnector.protocolHandlerInstantiationFailed"
      
        ), e);

        }

    }
      
    
    
        Connector的構造函數中第一步是根據
    
    protocol名稱HTTP/1.1,AJP/1.3或者protocol handler的類的全路徑名稱,下面是setProtocol方法的代碼實現:  
  
        
          public
        
        
          void
        
        
           setProtocol(String protocol) {



        
        
        
          if
        
        
           (AprLifecycleListener.isAprAvailable()) {

            
        
        
          if
        
         ("HTTP/1.1"
        
          .equals(protocol)) {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.http11.Http11AprProtocol"
        
          );

            } 
        
        
          else
        
        
          if
        
         ("AJP/1.3"
        
          .equals(protocol)) {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.ajp.AjpAprProtocol"
        
          );

            } 
        
        
          else
        
        
          if
        
         (protocol != 
        
          null
        
        
          ) {

                setProtocolHandlerClassName(protocol);

            } 
        
        
          else
        
        
           {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.http11.Http11AprProtocol"
        
          );

            }

        } 
        
        
          else
        
        
           {

            
        
        
          if
        
         ("HTTP/1.1"
        
          .equals(protocol)) {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.http11.Http11Protocol"
        
          );

            } 
        
        
          else
        
        
          if
        
         ("AJP/1.3"
        
          .equals(protocol)) {

                setProtocolHandlerClassName

                    (
        
        "org.apache.coyote.ajp.AjpProtocol"
        
          );

            } 
        
        
          else
        
        
          if
        
         (protocol != 
        
          null
        
        
          ) {

                setProtocolHandlerClassName(protocol);

            }

        }
        
      
View Code

  然后根據setProtocol方法設置的protocol handler進行實例化,在setProtocol方法中調用的setProtocolHandlerClassName方法,如下:

      
          public
      
      
        void
      
      
         setProtocolHandlerClassName(String protocolHandlerClassName) {



        
      
      
        this
      
      .protocolHandlerClassName =
      
         protocolHandlerClassName;



    }
      
    

  給connector的變量protocolHandlerClassName賦值,然后根據protocolHandlerClassName的值進行實例化。進而賦值給protocolHandler 變量。

  然后是方法createObjectNameKeyProperties,該方法的作用是將請求的address參數拼接成字符串,包括type,port。下面是代碼實現:  

        
          protected
        
        
           String createObjectNameKeyProperties(String type) {



        Object addressObj 
        
        = getProperty("address"
        
          );



        StringBuilder sb 
        
        = 
        
          new
        
         StringBuilder("type="
        
          );

        sb.append(type);

        sb.append(
        
        ",port="
        
          );

        
        
        
          int
        
         port =
        
           getPort();

        
        
        
          if
        
         (port > 0
        
          ) {

            sb.append(getPort());

        } 
        
        
          else
        
        
           {

            sb.append(
        
        "auto-"
        
          );

            sb.append(getProperty(
        
        "nameIndex"
        
          ));

        }

        String address 
        
        = ""
        
          ;

        
        
        
          if
        
         (addressObj 
        
          instanceof
        
        
           InetAddress) {

            address 
        
        =
        
           ((InetAddress) addressObj).getHostAddress();

        } 
        
        
          else
        
        
          if
        
         (addressObj != 
        
          null
        
        
          ) {

            address 
        
        =
        
           addressObj.toString();

        }

        
        
        
          if
        
         (address.length() > 0
        
          ) {

            sb.append(
        
        ",address="
        
          );

            sb.append(ObjectName.quote(address));

        }

        
        
        
          return
        
        
           sb.toString();

    }
        
      
View Code

  創建一個Request對象,Request是一個對Coyote Request的封裝,Coyote 這個東西很奇怪,是狼的意思,也不知道為什么外國人喜歡用動物名來給一個技術命名,hadoop,hive,pig等,說Coyote其實是對Socket的一個封裝,將Socket的請求和相應封裝成一個個Request和Response,具體如何封裝,都包涵什么信息等內容以后展開說明:

        
          public
        
        
           Request createRequest() {

        Request request 
        
        = 
        
          new
        
        
           Request();

        request.setConnector(
        
        
          this
        
        
          );

        
        
        
          return
        
        
           (request);

    }
        
      
View Code

  創建一個Response對象:

        
          public
        
        
           Response createResponse() {

        Response response 
        
        = 
        
          new
        
        
           Response();

        response.setConnector(
        
        
          this
        
        
          );

        
        
        
          return
        
        
           (response);

    }
        
      
View Code

  這里面值得注意的地方就是在request和response中,都有setConnector方法,所有connector是request和response的一個屬性。

  下面看方法destroyInternal,這個方法是在LifecycleMBeanBase類中定義的,用來銷毀mapperListener,protocolHandler從Service中移除這個Connector對象,代碼實現如下:  

        
           @Override

    
        
        
          protected
        
        
          void
        
         destroyInternal() 
        
          throws
        
        
           LifecycleException {

        mapperListener.destroy();



        
        
        
          try
        
        
           {

            protocolHandler.destroy();

        } 
        
        
          catch
        
        
           (Exception e) {

            
        
        
          throw
        
        
          new
        
        
           LifecycleException

                (sm.getString

                 (
        
        "coyoteConnector.protocolHandlerDestroyFailed"
        
          ), e);

        }



        
        
        
          if
        
         (getService() != 
        
          null
        
        
          ) {

            getService().removeConnector(
        
        
          this
        
        
          );

        }



        
        
        
          super
        
        
          .destroyInternal();

    }
        
      
View Code

  設置和獲取是否允許Trace方法的執行:  

        
          public
        
        
          void
        
         setAllowTrace(
        
          boolean
        
        
           allowTrace) {



        
        
        
          this
        
        .allowTrace =
        
           allowTrace;

        setProperty(
        
        "allowTrace"
        
          , String.valueOf(allowTrace));



    }




        
        
          public
        
        
          boolean
        
        
           getAllowTrace() {



        
        
        
          return
        
         (
        
          this
        
        
          .allowTrace);



    }
        
      
View Code

  設置和獲取異步請求的過期時間:  

        
          public
        
        
          void
        
         setAsyncTimeout(
        
          long
        
        
           asyncTimeout) {



        
        
        
          this
        
        .asyncTimeout=
        
           asyncTimeout;

        setProperty(
        
        "asyncTimeout"
        
          , String.valueOf(asyncTimeout));



    }


        
        
          public
        
        
          long
        
        
           getAsyncTimeout() {



        
        
        
          return
        
        
           asyncTimeout;



    }
        
      
View Code

  配置和獲取參數,參數這部分在前面的章節已經提到過了:

        
          public
        
        
          void
        
        
           setAttribute(String name, Object value) {

        setProperty(name, String.valueOf(value));

    }

 
        
        
          public
        
        
           Object getAttribute(String name) {

        
        
        
          return
        
        
           getProperty(name);

    }
        
      
View Code

  剩下的方法都是設置和獲取前面定義的變量的值。

  Server的主要接口已經介紹完了,下面看一下一些關鍵類的實現:

  Server接口的標準實現是StandardServer類,同時StandServer也繼承了LifecycleMBeanBase類,看一下StandardServer中幾個重要方法的實現:

查看tomcat啟動文件都干點啥---server對象

  找幾個重要的方法說明一下:

  向保存Connector的數組中添加新的Connector對象的方法addConnector,代碼實現如下:  

        
          public
        
        
          void
        
        
           addConnector(Connector connector) {



        
        
        
          synchronized
        
        
           (connectors) {

            connector.setService(
        
        
          this
        
        
          );

            Connector results[] 
        
        = 
        
          new
        
         Connector[connectors.length + 1
        
          ];

            System.arraycopy(connectors, 
        
        0, results, 0
        
          , connectors.length);

            results[connectors.length] 
        
        =
        
           connector;

            connectors 
        
        =
        
           results;



            
        
        
          if
        
        
           (getState().isAvailable()) {

                
        
        
          try
        
        
           {

                    connector.start();

                } 
        
        
          catch
        
        
           (LifecycleException e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.startFailed"
        
          ,

                            connector), e);

                }

            }



            
        
        
          //
        
        
           Report this property change to interested listeners
        
        

            support.firePropertyChange("connector", 
        
          null
        
        
          , connector);

        }



    }
        
      
View Code

  首先要把Connector和Serice做關聯,connector.setService(this),然后將要添加的connector對象添加到保存Connector對象的數組中,此處使用數組,完全是處于效率的考慮。然后查看當前Server對象的狀態,如果狀態合法的話,那么啟動添加的connector對象。然后在更改此Connector的狀態。

  返回Connector集合:  

        
          @Override

    
        
        
          public
        
        
           Connector[] findConnectors() {



        
        
        
          return
        
        
           (connectors);



    }
        
      
View Code

  在Connector集合中移除connector:  

        
          public
        
        
          void
        
        
           removeConnector(Connector connector) {



        
        
        
          synchronized
        
        
           (connectors) {

            
        
        
          int
        
         j = -1
        
          ;

            
        
        
          for
        
         (
        
          int
        
         i = 0; i < connectors.length; i++
        
          ) {

                
        
        
          if
        
         (connector ==
        
           connectors[i]) {

                    j 
        
        =
        
           i;

                    
        
        
          break
        
        
          ;

                }

            }

            
        
        
          if
        
         (j < 0
        
          )

                
        
        
          return
        
        
          ;

            
        
        
          if
        
        
           (connectors[j].getState().isAvailable()) {

                
        
        
          try
        
        
           {

                    connectors[j].stop();

                } 
        
        
          catch
        
        
           (LifecycleException e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.stopFailed"
        
          ,

                            connectors[j]), e);

                }

            }

            connector.setService(
        
        
          null
        
        
          );

            
        
        
          int
        
         k = 0
        
          ;

            Connector results[] 
        
        = 
        
          new
        
         Connector[connectors.length - 1
        
          ];

            
        
        
          for
        
         (
        
          int
        
         i = 0; i < connectors.length; i++
        
          ) {

                
        
        
          if
        
         (i !=
        
           j)

                    results[k
        
        ++] =
        
           connectors[i];

            }

            connectors 
        
        =
        
           results;



            
        
        
          //
        
        
           Report this property change to interested listeners
        
        

            support.firePropertyChange("connector", connector, 
        
          null
        
        
          );

        }



    }
        
      
View Code

  首先遍歷Connector集合,找到要移除的connector,如果指定的connector對象狀態合法,那么調用該connector的stop方法,然后將指定的connector對象關聯的Server置為null,剩下的內容就是整理移除connector對象的Connector集合。

  設置Container方法,該container對象處理Service中所有connector中的請求:  

        
          public
        
        
          void
        
        
           setContainer(Container container) {



        Container oldContainer 
        
        = 
        
          this
        
        
          .container;

        
        
        
          if
        
         ((oldContainer != 
        
          null
        
        ) && (oldContainer 
        
          instanceof
        
        
           Engine))

            ((Engine) oldContainer).setService(
        
        
          null
        
        
          );

        
        
        
          this
        
        .container =
        
           container;

        
        
        
          if
        
         ((
        
          this
        
        .container != 
        
          null
        
        ) && (
        
          this
        
        .container 
        
          instanceof
        
        
           Engine))

            ((Engine) 
        
        
          this
        
        .container).setService(
        
          this
        
        
          );

        
        
        
          if
        
         (getState().isAvailable() && (
        
          this
        
        .container != 
        
          null
        
        
          )) {

            
        
        
          try
        
        
           {

                
        
        
          this
        
        
          .container.start();

            } 
        
        
          catch
        
        
           (LifecycleException e) {

                
        
        
          //
        
        
           Ignore
        
        
                      }

        }

        
        
        
          if
        
         (getState().isAvailable() && (oldContainer != 
        
          null
        
        
          )) {

            
        
        
          try
        
        
           {

                oldContainer.stop();

            } 
        
        
          catch
        
        
           (LifecycleException e) {

                
        
        
          //
        
        
           Ignore
        
        
                      }

        }



        
        
        
          //
        
        
           Report this property change to interested listeners
        
        

        support.firePropertyChange("container", oldContainer, 
        
          this
        
        
          .container);



    }
        
      
View Code

  首先是處理這個Server中原有的Container,原來可能有Container也有可能沒有,所以要做判斷,如果存在的話,解除和Service的關聯,然后要處理新的container對象。關聯Service,啟動Container。

  由于Service中只有一個Container,所以沒有移除Container方法,在設置的時候其實是完成了刪除更新的操作。

  看一下startInternal方法:  

        
          protected
        
        
          void
        
         startInternal() 
        
          throws
        
        
           LifecycleException {



        
        
        
          if
        
        
          (log.isInfoEnabled())

            log.info(sm.getString(
        
        "standardService.start.name", 
        
          this
        
        
          .name));

        setState(LifecycleState.STARTING);



        
        
        
          //
        
        
           Start our defined Container first
        
        
          if
        
         (container != 
        
          null
        
        
          ) {

            
        
        
          synchronized
        
        
           (container) {

                container.start();

            }

        }



        
        
        
          synchronized
        
        
           (executors) {

            
        
        
          for
        
        
           (Executor executor: executors) {

                executor.start();

            }

        }



        
        
        
          //
        
        
           Start our defined Connectors second
        
        
          synchronized
        
        
           (connectors) {

            
        
        
          for
        
        
           (Connector connector: connectors) {

                
        
        
          try
        
        
           {

                    
        
        
          //
        
        
           If it has already failed, don't try and start it
        
        
          if
        
         (connector.getState() !=
        
           LifecycleState.FAILED) {

                        connector.start();

                    }

                } 
        
        
          catch
        
        
           (Exception e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.startFailed"
        
          ,

                            connector), e);

                }

            }

        }

    }
        
      
View Code

  該方法就是逐一啟動Service中的組件,Container,Executor,Connector。

  stopInternal方法:  

        
          protected
        
        
          void
        
         stopInternal() 
        
          throws
        
        
           LifecycleException {



        
        
        
          //
        
        
           Pause connectors first
        
        
          synchronized
        
        
           (connectors) {

            
        
        
          for
        
        
           (Connector connector: connectors) {

                
        
        
          try
        
        
           {

                    connector.pause();

                } 
        
        
          catch
        
        
           (Exception e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.pauseFailed"
        
          ,

                            connector), e);

                }

            }

        }



        
        
        
          if
        
        
          (log.isInfoEnabled())

            log.info(sm.getString(
        
        "standardService.stop.name", 
        
          this
        
        
          .name));

        setState(LifecycleState.STOPPING);



        
        
        
          //
        
        
           Stop our defined Container second
        
        
          if
        
         (container != 
        
          null
        
        
          ) {

            
        
        
          synchronized
        
        
           (container) {

                container.stop();

            }

        }



        
        
        
          //
        
        
           Now stop the connectors
        
        
          synchronized
        
        
           (connectors) {

            
        
        
          for
        
        
           (Connector connector: connectors) {

                
        
        
          if
        
         (!
        
          LifecycleState.STARTED.equals(

                        connector.getState())) {

                    
        
        
          //
        
        
           Connectors only need stopping if they are currently

                    
        
        
          //
        
        
           started. They may have failed to start or may have been

                    
        
        
          //
        
        
           stopped (e.g. via a JMX call)
        
        
          continue
        
        
          ;

                }

                
        
        
          try
        
        
           {

                    connector.stop();

                } 
        
        
          catch
        
        
           (Exception e) {

                    log.error(sm.getString(

                            
        
        "standardService.connector.stopFailed"
        
          ,

                            connector), e);

                }

            }

        }



        
        
        
          synchronized
        
        
           (executors) {

            
        
        
          for
        
        
           (Executor executor: executors) {

                executor.stop();

            }

        }

    }
        
      
View Code

  由這兩個方法也能看出來Lifecycle對于個個組件生命周期的一致的生命周期的管理機制。

  其實最開始想用本章說一下如何構建Server,但是覺得還是有必要將Server中的內容展開說明一下,在說如果構建的話可能更好理解。所以就有了這個只是具有說明意義的一節。?

查看tomcat啟動文件都干點啥---server對象


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美一区二区在线免费观看 | 欧美另类交视频 | 五月婷婷开心综合 | 国产在线19禁免费观看国产 | 视频一区在线免费观看 | 久久国产一片免费观看 | 女人一级一级毛片 | 亚洲欧美日韩国产精品网 | 国产美女久久久亚洲 | 涩涩色中文综合亚洲 | 久久99国产亚洲高清观看首页 | 久久久久久国产精品三级 | 久久久免费精品视频 | 国产女人18一级毛片视频 | 综合久久久久综合体桃花网 | 午夜精品久久久久久久第一页 | 好好的曰com久久 | 在线观看色视频 | 在线视频福利 | 亚洲自拍第二页 | h片在线观看 | 国产伦精品一区二区三区在线观看 | 亚洲欧美激情综合第一区 | 手机在线看片福利 | 香蕉国产在线 | 黄色成人免费网站 | 欧美一区二区三区久久久人妖 | 国产伦精品一区二区三区免 | 日韩不卡中文字幕 | 欧美成人欧美激情欧美风情 | 国产青草亚洲香蕉精品久久 | 欧美久久久久久久久 | 九九99久久精品国产 | 欧美激情日本一道免费视频 | 一区二区亚洲视频 | 九九热线 | 久久亚洲精品中文字幕二区 | 97影院九七影院理论片 | 一区二区三区四区视频在线观看 | 奇米在线免费视频 | 日韩在线网 |