免费观看又色又爽又黄的小说免费_美女福利视频国产片_亚洲欧美精品_美国一级大黄大色毛片

查漏補缺:連接器在Tomcat中是如何設計的

2021-02-23    分類: 網站建設

從連接器(Connector)源碼說起

既然是來解析連接器(Connector),那么我們直接從源碼入手,后面所有源碼我會剔除不重要部分,所以會忽略大部分源碼細節,只關注流程。源碼如下(高能預警,大量代碼):

  1. public class Connector extends LifecycleMBeanBase { 
  2.  public Connector() { 
  3.  this("org.apache.coyote.http11.Http11NioProtocol"); 
  4.  } 
  5.  public Connector(String protocol) { 
  6.  boolean aprConnector = AprLifecycleListener.isAprAvailable() && 
  7.  AprLifecycleListener.getUseAprConnector(); 
  8.  if ("HTTP/1.1".equals(protocol) || protocol == null) { 
  9.  if (aprConnector) { 
  10.  protocolHandlerClassName = "org.apache.coyote.http11.Http11AprProtocol"; 
  11.  } else { 
  12.  protocolHandlerClassName = "org.apache.coyote.http11.Http11NioProtocol"; 
  13.  } 
  14.  } else if ("AJP/1.3".equals(protocol)) { 
  15.  if (aprConnector) { 
  16.  protocolHandlerClassName = "org.apache.coyote.ajp.AjpAprProtocol"; 
  17.  } else { 
  18.  protocolHandlerClassName = "org.apache.coyote.ajp.AjpNioProtocol"; 
  19.  } 
  20.  } else { 
  21.  protocolHandlerClassName = protocol; 
  22.  } 
  23.  // Instantiate protocol handler 
  24.  ProtocolHandler p = null; 
  25.  try { 
  26.  Class<?> clazz = Class.forName(protocolHandlerClassName); 
  27.  p = (ProtocolHandler) clazz.getConstructor().newInstance(); 
  28.  } catch (Exception e) { 
  29.  log.error(sm.getString( 
  30.  "coyoteConnector.protocolHandlerInstantiationFailed"), e); 
  31.  } finally { 
  32.  this.protocolHandler = p; 
  33.  } 
  34.  // Default for Connector depends on this system property 
  35.  setThrowOnFailure(Boolean.getBoolean("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE")); 
  36.  } 

我們來看看Connector的構造方法,其實只做了一件事情,就是根據協議設置對應的ProtocolHandler,根據名稱我們知道,這是協議處理類,所以連接器內部的一個重要子模塊就是ProtocolHandler。

關于生命周期

我們看到Connector繼承了LifecycleMBeanBase,我們來看看Connector的最終繼承關系:

金九銀十,查漏補缺:連接器在Tomcat中是如何設計的

我們看到最終實現的是Lifecycle接口,我們看看這個接口是何方神圣。我把其接口的注釋拿下來解釋下

  1. /** 
  2.  * Common interface for component life cycle methods. Catalina components 
  3.  * may implement this interface (as well as the appropriate interface(s) for 
  4.  * the functionality they support) in order to provide a consistent mechanism 
  5.  * to start and stop the component. 
  6.  * start() 
  7.  * ----------------------------- 
  8.  * | | 
  9.  * | init() | 
  10.  * NEW -?-- INITIALIZING | 
  11.  * | | | | ------------------?----------------------- 
  12.  * | | |auto | | | 
  13.  * | | \|/ start() \|/ \|/ auto auto stop() | 
  14.  * | | INITIALIZED --?-- STARTING_PREP --?- STARTING --?- STARTED --?--- | 
  15.  * | | | | | 
  16.  * | |destroy()| | | 
  17.  * | --?-----?-- ------------------------?-------------------------------- ^ 
  18.  * | | | | 
  19.  * | | \|/ auto auto start() | 
  20.  * | | STOPPING_PREP ----?---- STOPPING ------?----- STOPPED -----?----- 
  21.  * | \|/ ^ | ^ 
  22.  * | | stop() | | | 
  23.  * | | -------------------------- | | 
  24.  * | | | | | 
  25.  * | | | destroy() destroy() | | 
  26.  * | | FAILED ----?------ DESTROYING ---?----------------- | 
  27.  * | | ^ | | 
  28.  * | | destroy() | |auto | 
  29.  * | --------?----------------- \|/ | 
  30.  * | DESTROYED | 
  31.  * | | 
  32.  * | stop() | 
  33.  * ----?-----------------------------?------------------------------ 
  34.  * 
  35.  * Any state can transition to FAILED. 
  36.  * 
  37.  * Calling start() while a component is in states STARTING_PREP, STARTING or 
  38.  * STARTED has no effect. 
  39.  * 
  40.  * Calling start() while a component is in state NEW will cause init() to be 
  41.  * called immediately after the start() method is entered. 
  42.  * 
  43.  * Calling stop() while a component is in states STOPPING_PREP, STOPPING or 
  44.  * STOPPED has no effect. 
  45.  * 
  46.  * Calling stop() while a component is in state NEW transitions the component 
  47.  * to STOPPED. This is typically encountered when a component fails to start and 
  48.  * does not start all its sub-components. When the component is stopped, it will 
  49.  * try to stop all sub-components - even those it didn't start. 
  50.  * 
  51.  * Attempting any other transition will throw {@link LifecycleException}. 
  52.  * 
  53.  * </pre> 
  54.  * The {@link LifecycleEvent}s fired during state changes are defined in the 
  55.  * methods that trigger the changed. No {@link LifecycleEvent}s are fired if the 
  56.  * attempted transition is not valid. 
  57. 這段注釋翻譯就是,這個接口是提供給組件聲明周期管理的,并且提供了聲明周期流轉圖。這里我們只需要知道正常流程即可:

    1. New--->Init()---->Start()---->Stop()--->Destory() 

    從生命周期探索連接器

    根據上面的生命周期說明,我們可以知道連接器(Connector)就是按照如此的聲明周期管理的,所以我們找到了線索,所以連接器肯定會先初始化然后再啟動。我們查看其initInternal()方法可以知道連接器初始化做了什么事情,源碼如下:

    1. @Override 
    2.  protected void initInternal() throws LifecycleException { 
    3.  super.initInternal(); 
    4.  if (protocolHandler == null) { 
    5.  throw new LifecycleException( 
    6.  sm.getString("coyoteConnector.protocolHandlerInstantiationFailed")); 
    7.  } 
    8.  // Initialize adapter 
    9.  adapter = new CoyoteAdapter(this); 
    10.  protocolHandler.setAdapter(adapter); 
    11.  if (service != null) { 
    12.  protocolHandler.setUtilityExecutor(service.getServer().getUtilityExecutor()); 
    13.  } 
    14.  // Make sure parseBodyMethodsSet has a default 
    15.  if (null == parseBodyMethodsSet) { 
    16.  setParseBodyMethods(getParseBodyMethods()); 
    17.  } 
    18.  if (protocolHandler.isAprRequired() && !AprLifecycleListener.isInstanceCreated()) { 
    19.  throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprListener", 
    20.  getProtocolHandlerClassName())); 
    21.  } 
    22.  if (protocolHandler.isAprRequired() && !AprLifecycleListener.isAprAvailable()) { 
    23.  throw new LifecycleException(sm.getString("coyoteConnector.protocolHandlerNoAprLibrary", 
    24.  getProtocolHandlerClassName())); 
    25.  } 
    26.  if (AprLifecycleListener.isAprAvailable() && AprLifecycleListener.getUSEOpenssl() && 
    27.  protocolHandler instanceof AbstractHttp11JsseProtocol) { 
    28.  AbstractHttp11JsseProtocol<?> jsseProtocolHandler = 
    29.  (AbstractHttp11JsseProtocol<?>) protocolHandler; 
    30.  if (jsseProtocolHandler.issslEnabled() && 
    31.  jsseProtocolHandler.getsslImplementationName() == null) { 
    32.  // Openssl is compatible with the JSSE configuration, so use it if APR is available 
    33.  jsseProtocolHandler.setsslImplementationName(OpensslImplementation.class.getName()); 
    34.  } 
    35.  } 
    36.  try { 
    37.  protocolHandler.init(); 
    38.  } catch (Exception e) { 
    39.  throw new LifecycleException( 
    40.  sm.getString("coyoteConnector.protocolHandlerInitializationFailed"), e); 
    41.  } 
    42.  } 

    根據上面源碼,我們發現主要是處理protocolHandler并初始化它,同時我們注意到了protocolHandler 設置了一個適配器,我們看看這個適配器是做啥的,跟蹤源碼如下:

    1. /** 
    2.  * The adapter, used to call the connector. 
    3.  * 
    4.  *&nbs

      網頁題目:查漏補缺:連接器在Tomcat中是如何設計的
      瀏覽路徑:http://m.newbst.com/news44/102494.html

      成都網站建設公司_創新互聯,為您提供搜索引擎優化App設計定制網站網站建設微信小程序域名注冊

      廣告

      聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

    外貿網站制作