欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Tomcat源碼分析(三)--連接器是如何與容器關聯的

系統 1917 0
本系列轉載自?http://blog.csdn.net/haitao111313/article/category/1179996?

這篇文章要弄懂一個問題,我們知道,一個鏈接器是跟一個容器關聯的, 容器跟鏈接器是在什么時候關聯上的?

  在明白這個問題前要先了解一下Digester庫,這個庫簡單的說就是解析xml文件,這里有兩個概念:模式和規則,所謂模式就是一個xml的標簽,規則就是遇到一個xml標簽需要做什么,看一下他主要的三個方法:

? ? ? 1:addObjectCreate(String pattern, String className, String attributeName) ? ?根據模式pattern實例化一個對象className

? ? ? 2:addSetProperties(String pattern) ? 設置這個模式的屬性

? ? ? 3:addSetNext(String pattern, String methodName, String paramType) ?添加模式之間的關系,調用父模式的

? ? 上面可能不好理解,看tomcat是怎么用到Digester的,在org.apache.catalina.startup.Catalina.createStartDigester()的方法里(這個方法是在服務組件啟動的時候調用的,詳細參考 Tomcat源碼分析(一)--服務啟動 ),在這個方法里有使用Digester來解析server.xml文件:

? ??

  1. digester.addObjectCreate( "Server/Service" ,??
  2. ???????????????????????????????? "org.apache.catalina.core.StandardService" ,??
  3. ???????????????????????????????? "className" ); //?添加一個模式“Server/Service”,當在xml文件(這里是server.xml)里遇到“Server”標簽下的Service標簽的時候,根據標簽Service的屬性“className”為類名實例化一個對象,默認類名是"org.apache.catalina.core.StandardServer" ??
  4. ???????digester.addSetProperties( "Server/Service" );? //設置對象StandardService的屬性,有些什么屬性由xml里的Service標簽指定 ??
  5. ???????digester.addSetNext( "Server/Service" ,??
  6. ??????????????????????????? "addService" ,??
  7. ??????????????????????????? "org.apache.catalina.Service" ); //調用Service標簽的上一級標簽Server的對象(即StandardServer)的addService方法,把Service添加進Server,設置它們的關系,最后一個參數表示addService方法的參數類型 ??
這樣StandardServer和StandardService便有了所屬關系,現在看容器跟鏈接器是怎么連接的,再看createStartDigester方法:

  1. digester.addObjectCreate( "Server/Service/Connector" ,??
  2. ????????????????????????????????? "org.apache.catalina.connector.http.HttpConnector" ,??
  3. ????????????????????????????????? "className" );??
  4. ????????digester.addSetProperties( "Server/Service/Connector" );??
  5. ????????digester.addSetNext( "Server/Service/Connector" ,??
  6. ???????????????????????????? "addConnector" ,??
  7. ???????????????????????????? "org.apache.catalina.Connector" );??

這里很好理解,跟上面的是一樣的,遇到標簽Server/Service/Connector的時候(這里簡化了說法,應該是標簽Server下的子標簽Service的子標簽Connector,有點拗口),實例化HttpConnector,然后在它的上一級父容器StandardService下調用addConnector,這樣就把鏈接器HttpConnector添加進容器StandardService下了,看StandardService的addConnector方法:

  1. public ? void ?addConnector(Connector?connector)?{??
  2. ????? synchronized ?(connectors)?{??
  3. ?????????connector.setContainer( this .container);? //本來這里就應該把容器和連接器關聯上的,但是在一開始tomcat啟動的時候,Digester是先添加鏈接器,所以容器container還是為null的,但是沒有關系,后面還會另一個地方關聯他們,這里應該牢記的是容器和連接器都是在Service里面 ??
  4. ?????????connector.setService( this );??
  5. ?????????Connector?results[]?=? new ?Connector[connectors.length?+? 1 ];??
  6. ?????????System.arraycopy(connectors,? 0 ,?results,? 0 ,?connectors.length);??
  7. ?????????results[connectors.length]?=?connector;??
  8. ?????????connectors?=?results;??
  9. ??
  10. ????????? if ?(initialized)?{??
  11. ????????????? try ?{??
  12. ?????????????????connector.initialize();??
  13. ?????????????}? catch ?(LifecycleException?e)?{??
  14. ?????????????????e.printStackTrace(System.err);??
  15. ?????????????}??
  16. ?????????}??
  17. ??
  18. ????????? if ?(started?&&?(connector? instanceof ?Lifecycle))?{??
  19. ????????????? try ?{??
  20. ?????????????????((Lifecycle)?connector).start();??
  21. ?????????????}? catch ?(LifecycleException?e)?{??
  22. ?????????????????;??
  23. ?????????????}??
  24. ?????????}??
  25. ??
  26. ????????? //?Report?this?property?change?to?interested?listeners ??
  27. ?????????support.firePropertyChange( "connector" ,? null ,?connector);??
  28. ?????}??
  29. ??
  30. ?}??
這個方法很簡單,就是把一個鏈接器connector添加到StandardService的connectors數組里,然后關聯上StandardService的容器。代碼上也做了一點說明(很重要)。連接器添加進StandardService了,現在看容器是什么時候添加進StandardService的,其實方法是一樣的,再回到createStartDigester方法:

  1. digester.addRuleSet( new ?EngineRuleSet( "Server/Service/" )); //這句代碼是在createStartDigester方法里面 ??
  2. --------------------------》下面進入EngineRuleSet類的addRuleInstances方法??
  3. public ? void ?addRuleInstances(Digester?digester)?{??
  4. ???????digester.addObjectCreate(prefix?+? "Engine" ,??
  5. ???????????????????????????????? "org.apache.catalina.core.StandardEngine" ,??
  6. ???????????????????????????????? "className" );??
  7. ???????digester.addSetProperties(prefix?+? "Engine" );??
  8. ???????digester.addRule(prefix?+? "Engine" ,??
  9. ???????????????????????? new ?LifecycleListenerRule??
  10. ????????????????????????(digester,??
  11. ????????????????????????? "org.apache.catalina.startup.EngineConfig" ,??
  12. ????????????????????????? "engineConfigClass" ));??
  13. ???????digester.addSetNext(prefix?+? "Engine" ,??
  14. ??????????????????????????? "setContainer" ,??
  15. ??????????????????????????? "org.apache.catalina.Container" );? //這里調用StandardService的方法setContainer方法,把容器添加進StandardService里面 ??
先不去糾結Digester是怎么進入addRuleInstances方法的,當我們調用了digester.addRuleSet(new EngineRuleSet("Server/Service/"));方法,Digester便會自動調用到EngineRuleSet類的addRuleInstances方法,在方法里面無非也是添加各種模式和規則,根據上面的添加規則,很容易知道這里又添加了一個StandardEngine對象(容器),然后又在該模式的上一級模式Server/Service添加StandardEngine跟StandardService的關系,即通過setContainer方法把容器添加進StandardService里。以下是StandardService的setContainer方法:

  1. public ? void ?setContainer(Container?container)?{??
  2. ?????Container?oldContainer?=? this .container;??
  3. ????? if ?((oldContainer?!=? null )?&&?(oldContainer? instanceof ?Engine))??
  4. ?????????((Engine)?oldContainer).setService( null );??
  5. ????? this .container?=?container;??
  6. ????? if ?(( this .container?!=? null )?&&?( this .container? instanceof ?Engine))??
  7. ?????????((Engine)? this .container).setService( this );??
  8. ????? if ?(started?&&?( this .container?!=? null )?&&??
  9. ?????????( this .container? instanceof ?Lifecycle))?{??
  10. ????????? try ?{??
  11. ?????????????((Lifecycle)? this .container).start();??
  12. ?????????}? catch ?(LifecycleException?e)?{??
  13. ?????????????;??
  14. ?????????}??
  15. ?????}????????????????????????????????????? //重點!!!!!!!! ??
  16. ????? synchronized ?(connectors)?{??????????? //下面是把StandardService下的所有連接器都關聯上StandardService下的容器,這樣連接器就跟容器關聯上了。 ??
  17. ????????? for ?( int ?i?=? 0 ;?i?<?connectors.length;?i++)??
  18. ?????????????connectors[i].setContainer( this .container);??
  19. ?????}??
  20. ????? if ?(started?&&?(oldContainer?!=? null )?&&??
  21. ?????????(oldContainer? instanceof ?Lifecycle))?{??
  22. ????????? try ?{??
  23. ?????????????((Lifecycle)?oldContainer).stop();??
  24. ?????????}? catch ?(LifecycleException?e)?{??
  25. ?????????????;??
  26. ?????????}??
  27. ?????}??
  28. ??
  29. ????? //?Report?this?property?change?to?interested?listeners ??
  30. ?????support.firePropertyChange( "container" ,?oldContainer,? this .container);??
  31. ??
  32. ?}??

上面的代碼做了各種判斷,然后把容器設置到StandardService下,在“同步代碼塊”處,把容器和鏈接器關聯上了,至此,容器和鏈接器就關聯上了。回過頭想想,其實很簡單,就是用Digester根據設定的模式讀取server.xml,然后調用了兩個關鍵的方法setContainer和addConnector,就把容器和鏈接器關聯上了。關聯上了就可以明白在 Tomcat源碼分析(二)--連接處理 一文的最后process方法里代碼: connector.getContainer().invoke(request,?response);的含義了。下篇希望說明白調用invoke之后發生的一切。

Tomcat源碼分析(三)--連接器是如何與容器關聯的?


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 三级理论中文字幕在线播放 | 精品视频久久 | 欧美自拍视频在线 | 91精品一区二区三区久久久久久 | 国产精品福利短视在线播放频 | 91丨九色丨首页在线观看 | 九九九热在线精品免费全部 | 999精品国产人妻无码系列久久 | 国产一区二区精品久久91 | 日韩欧美福利视频 | 侮辱丰满美丽的人妻 | 日本九九精品一区二区 | 日本高免费观看在线播放 | 青青草视频免费观看 | 精品久| 有一婷婷色| 涩涩小网站 | 综合久久久| 91久久亚洲国产成人精品性色 | 国产精品揄拍100视频最近 | 激情男女视频 | 国内精品视频在线观看 | 污网站免费 | 免费福利在线观看 | 久久久精 | 婷婷免费视频 | 青草免费观看 | av网站免费观看 | 亚洲精品久久久久一区二区三 | 国产精品久久久久无码AV1 | 国产精品久久久久久久久久久新郎 | 国产欧美精品一区二区三区 | 亚洲精品国产成人一区二区 | 最新国产精品 | 国产日产亚洲欧美综合另类 | 婷婷综合网站 | 亚洲一区国产 | 99久久精品费精品国产一区二区 | 亚洲一区二区三区日本久久九 | 欧美性成人 | 久久福利一区 |