中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

查漏補(bǔ)缺:連接器在Tomcat中是如何設(shè)計(jì)的

2021-02-23    分類: 網(wǎng)站建設(shè)

從連接器(Connector)源碼說(shuō)起

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

  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.  } 

我們來(lái)看看Connector的構(gòu)造方法,其實(shí)只做了一件事情,就是根據(jù)協(xié)議設(shè)置對(duì)應(yīng)的ProtocolHandler,根據(jù)名稱我們知道,這是協(xié)議處理類,所以連接器內(nèi)部的一個(gè)重要子模塊就是ProtocolHandler。

關(guān)于生命周期

我們看到Connector繼承了LifecycleMBeanBase,我們來(lái)看看Connector的最終繼承關(guān)系:

金九銀十,查漏補(bǔ)缺:連接器在Tomcat中是如何設(shè)計(jì)的

我們看到最終實(shí)現(xiàn)的是Lifecycle接口,我們看看這個(gè)接口是何方神圣。我把其接口的注釋拿下來(lái)解釋下

  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.  *  
  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. 這段注釋翻譯就是,這個(gè)接口是提供給組件聲明周期管理的,并且提供了聲明周期流轉(zhuǎn)圖。這里我們只需要知道正常流程即可:

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

    從生命周期探索連接器

    根據(jù)上面的生命周期說(shuō)明,我們可以知道連接器(Connector)就是按照如此的聲明周期管理的,所以我們找到了線索,所以連接器肯定會(huì)先初始化然后再啟動(dòng)。我們查看其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.  } 

    根據(jù)上面源碼,我們發(fā)現(xiàn)主要是處理protocolHandler并初始化它,同時(shí)我們注意到了protocolHandler 設(shè)置了一個(gè)適配器,我們看看這個(gè)適配器是做啥的,跟蹤源碼如下:

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

      本文名稱:查漏補(bǔ)缺:連接器在Tomcat中是如何設(shè)計(jì)的
      鏈接分享:http://www.rwnh.cn/news/102494.html

      成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站營(yíng)銷微信公眾號(hào)、品牌網(wǎng)站建設(shè)網(wǎng)站制作、ChatGPT

      廣告

      聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

    搜索引擎優(yōu)化
    红原县| 民乐县| 遂川县| 中超| 萍乡市| 宕昌县| 桃江县| 江川县| 稻城县| 沽源县| 黄大仙区| 三河市| 黄浦区| 定日县| 和田市| 贵定县| 贞丰县| 玛纳斯县| 麟游县| 宁乡县| 山东省| 门头沟区| 烟台市| 自贡市| 白沙| 定西市| 周宁县| 双鸭山市| 图片| 彭州市| 天等县| 大连市| 博客| 高阳县| 资溪县| 牟定县| 化隆| 灵石县| 茶陵县| 大洼县| 含山县|