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

Tomcat源碼分析(十)--部署器

系統(tǒng) 1917 0

本系列轉(zhuǎn)載自?http://blog.csdn.net/haitao111313/article/category/1179996?

? 我們知道,在Tomcat的世界里,一個(gè)Host容器代表一個(gè)虛機(jī)器資源,Context容器代表一個(gè)應(yīng)用,所謂的部署器就是能夠把Context容器添加進(jìn)Host容器中去的一個(gè)組件。顯然,一個(gè)Host容器應(yīng)該擁有一個(gè)部署器組件。簡(jiǎn)單的部署代碼應(yīng)該是下面這樣的:

  1. Context?context?=? new ?StandardContext();??
  2. Host?host?=? new ?StandardHost();??
  3. host.addChild(context);??
別看這簡(jiǎn)單,其實(shí)這就是核心的部署代碼。當(dāng)然,Tomcat的部署器絕不是這么點(diǎn)東西,但其實(shí)也是比較簡(jiǎn)單的東西。在Catalina的createStartDigester()方法中(具體怎么調(diào)用到這個(gè)方法,詳細(xì)參考 Tomcat源碼分析(一)--服務(wù)啟動(dòng) ),向StandardHost容器中添加了一個(gè)HostConfig的實(shí)例。HostConfig類實(shí)現(xiàn)了LifecycleListener接口,也就是說它是個(gè)監(jiān)聽器類,能監(jiān)聽到組件的生命周期事件(有關(guān)生命周期的東西請(qǐng)參看 ?Tomcat源碼分析(七)--單一啟動(dòng)/關(guān)閉機(jī)制(生命周期) )。? 下面看接受事件的方法lifecycleEvent(LifecycleEvent)做了寫什么工作:

  1. public ? void ?lifecycleEvent(LifecycleEvent?event)?{??
  2. ??
  3. ???????? //?Identify?the?host?we?are?associated?with ??
  4. ???????? try ?{??
  5. ????????????host?=?(Host)?event.getLifecycle();??
  6. ???????????? if ?(host? instanceof ?StandardHost)?{? //如果監(jiān)聽到的事件對(duì)象類型是StandardHost就設(shè)置相關(guān)屬性。 ??
  7. ???????????????? int ?hostDebug?=?((StandardHost)?host).getDebug();??
  8. ???????????????? if ?(hostDebug?>? this .debug)?{??
  9. ???????????????????? this .debug?=?hostDebug;??
  10. ????????????????}??
  11. ????????????????setDeployXML(((StandardHost)?host).isDeployXML()); //是否發(fā)布xml文件的標(biāo)識(shí),默認(rèn)為true ??
  12. ????????????????setLiveDeploy(((StandardHost)?host).getLiveDeploy()); //是否動(dòng)態(tài)部署標(biāo)識(shí),默認(rèn)為true ??
  13. ????????????????setUnpackWARs(((StandardHost)?host).isUnpackWARs()); //是否要將war文件解壓縮,默認(rèn)為true ??
  14. ????????????}??
  15. ????????}? catch ?(ClassCastException?e)?{??
  16. ????????????log(sm.getString( "hostConfig.cce" ,?event.getLifecycle()),?e);??
  17. ???????????? return ;??
  18. ????????}??
  19. ??
  20. ???????? //?Process?the?event?that?has?occurred ??
  21. ???????? if ?(event.getType().equals(Lifecycle.START_EVENT))? //監(jiān)聽到容器開始,則調(diào)用start方法,方法里面調(diào)用了部署應(yīng)用的代碼 ??
  22. ????????????start();??
  23. ???????? else ? if ?(event.getType().equals(Lifecycle.STOP_EVENT))??
  24. ????????????stop();??
  25. ??
  26. ????}??
如果監(jiān)聽到StandardHost容器啟動(dòng)開始了,則調(diào)用start方法來,下面看start方法:

  1. protected ? void ?start()?{??
  2. ??
  3. ??????? if ?(debug?>=? 1 )??
  4. ???????????log(sm.getString( "hostConfig.start" ));??
  5. ??
  6. ??????? if ?(host.getAutoDeploy())?{??
  7. ???????????deployApps(); //發(fā)布應(yīng)用 ??
  8. ???????}??
  9. ??
  10. ??????? if ?(isLiveDeploy())?{??
  11. ???????????threadStart(); //動(dòng)態(tài)發(fā)布應(yīng)用,因?yàn)镠ostConfig也實(shí)現(xiàn)了Runnable接口,threadStart啟動(dòng)該線程來實(shí)現(xiàn)動(dòng)態(tài)發(fā)布 ??
  12. ???????}??
  13. ??
  14. ???}??
  15. ??--------------------》deployApps方法,該方法會(huì)把webapps目錄下的所有目錄都看作成一個(gè)應(yīng)用程序??
  16. ???? protected ? void ?deployApps()?{??
  17. ??
  18. ??????? if ?(!(host? instanceof ?Deployer))??
  19. ??????????? return ;??
  20. ??????? if ?(debug?>=? 1 )??
  21. ???????????log(sm.getString( "hostConfig.deploying" ));??
  22. ??
  23. ???????File?appBase?=?appBase(); //返回webapps目錄 ??
  24. ??????? if ?(!appBase.exists()?||?!appBase.isDirectory())??
  25. ??????????? return ;??
  26. ???????String?files[]?=?appBase.list(); //列出webapps目錄下的所有文件 ??
  27. ??
  28. ???????deployDescriptors(appBase,?files); //通過描述符發(fā)布應(yīng)用 ??
  29. ???????deployWARs(appBase,?files); //發(fā)布war文件的應(yīng)用 ??
  30. ???????deployDirectories(appBase,?files); //發(fā)布目錄型的應(yīng)用 ??
  31. ??
  32. ???}??

以上三個(gè)發(fā)布應(yīng)用的方式大同小異,所以只說說常用的發(fā)布方式--目錄型的應(yīng)用,下面看看deployDirectories方法,只寫了關(guān)鍵的邏輯:

  1. protected ? void ?deployDirectories(File?appBase,?String[]?files)?{??
  2. ??
  3. ????? for ?( int ?i?=? 0 ;?i?<?files.length;?i++)?{??
  4. ??
  5. ????????? if ?(files[i].equalsIgnoreCase( "META-INF" ))??
  6. ????????????? continue ;??
  7. ????????? if ?(files[i].equalsIgnoreCase( "WEB-INF" ))??
  8. ????????????? continue ;??
  9. ????????? if ?(deployed.contains(files[i]))??
  10. ????????????? continue ;??
  11. ?????????File?dir?=? new ?File(appBase,?files[i]);??
  12. ????????? if ?(dir.isDirectory())?{??
  13. ??
  14. ?????????????deployed.add(files[i]);??
  15. ??
  16. ????????????? //?Make?sure?there?is?an?application?configuration?directory ??
  17. ????????????? //?This?is?needed?if?the?Context?appBase?is?the?same?as?the ??
  18. ????????????? //?web?server?document?root?to?make?sure?only?web?applications ??
  19. ????????????? //?are?deployed?and?not?directories?for?web?space. ??
  20. ?????????????File?webInf?=? new ?File(dir,? "/WEB-INF" );??
  21. ????????????? if ?(!webInf.exists()?||?!webInf.isDirectory()?||??
  22. ?????????????????!webInf.canRead())??
  23. ????????????????? continue ;??
  24. ??
  25. ????????????? //?Calculate?the?context?path?and?make?sure?it?is?unique ??
  26. ?????????????String?contextPath?=? "/" ?+?files[i];??
  27. ????????????? if ?(files[i].equals( "ROOT" ))??
  28. ?????????????????contextPath?=? "" ;??
  29. ????????????? if ?(host.findChild(contextPath)?!=? null )??
  30. ????????????????? continue ;??
  31. ??
  32. ????????????? //?Deploy?the?application?in?this?directory ??
  33. ?????????????log(sm.getString( "hostConfig.deployDir" ,?files[i]));??
  34. ????????????? try ?{??
  35. ?????????????????URL?url?=? new ?URL( "file" ,? null ,?dir.getCanonicalPath()); //得到應(yīng)用的路徑,路徑的寫法是???file://應(yīng)用名稱 ??
  36. ?????????????????((Deployer)?host).install(contextPath,?url);? //安裝應(yīng)用到目錄下 ??
  37. ?????????????}? catch ?(Throwable?t)?{??
  38. ?????????????????log(sm.getString( "hostConfig.deployDir.error" ,?files[i]),??
  39. ?????????????????????t);??
  40. ?????????????}??
  41. ??
  42. ?????????}??
  43. ??
  44. ?????}??
  45. ??
  46. ?}??

((Deployer) host).install(contextPath, url);會(huì)調(diào)用到StandardHost的install方法,再由StandardHost轉(zhuǎn)交給StandardHostDeployer的install方法,StandardHostDeployer是一個(gè)輔助類,幫助StandardHost來實(shí)現(xiàn)發(fā)布應(yīng)用,它實(shí)現(xiàn)了Deployer接口,看它的install(URL config, URL war)方法(它有兩個(gè)install方法,分別用來發(fā)布上面不同方式的應(yīng)用):

  1. public ? synchronized ? void ?install(String?contextPath,?URL?war)??
  2. ??????? throws ?IOException?{??
  3. ??
  4. ?????..............................................??
  5. ??
  6. ??????? //?Calculate?the?document?base?for?the?new?web?application ??
  7. ???????host.log(sm.getString( "standardHost.installing" ,??
  8. ?????????????????????????????contextPath,?war.toString()));??
  9. ???????String?url?=?war.toString();??
  10. ???????String?docBase?=? null ;??
  11. ??????? if ?(url.startsWith( "jar:" ))?{??? //如果是war類型的應(yīng)用 ??
  12. ???????????url?=?url.substring( 4 ,?url.length()?-? 2 );??
  13. ???????}??
  14. ??????? if ?(url.startsWith( "file://" ))//如果是目錄類型的應(yīng)用??
  15. ???????????docBase?=?url.substring( 7 );??
  16. ??????? else ? if ?(url.startsWith( "file:" ))??
  17. ???????????docBase?=?url.substring( 5 );??
  18. ??????? else ??
  19. ??????????? throw ? new ?IllegalArgumentException??
  20. ???????????????(sm.getString( "standardHost.warURL" ,?url));??
  21. ??
  22. ??????? //?Install?the?new?web?application ??
  23. ??????? try ?{??
  24. ???????????Class?clazz?=?Class.forName(host.getContextClass()); //host.getContextClass得到的其實(shí)是StandardContext, ??
  25. ???????????Context?context?=?(Context)?clazz.newInstance();??
  26. ???????????context.setPath(contextPath); //設(shè)置該context的訪問路徑為contextPath,即我們的應(yīng)用訪問路徑 ??
  27. ?????????????
  28. ???????????context.setDocBase(docBase); //設(shè)置該應(yīng)用在磁盤的路徑 ??
  29. ??????????? if ?(context? instanceof ?Lifecycle)?{??
  30. ???????????????clazz?=?Class.forName(host.getConfigClass()); //實(shí)例化host的監(jiān)聽器類,并關(guān)聯(lián)上context ??
  31. ???????????????LifecycleListener?listener?=??
  32. ???????????????????(LifecycleListener)?clazz.newInstance();??
  33. ???????????????((Lifecycle)?context).addLifecycleListener(listener);??
  34. ???????????}??
  35. ???????????host.fireContainerEvent(PRE_INSTALL_EVENT,?context);??
  36. ???????????host.addChild(context);??????????? //添加到host實(shí)例,即把context應(yīng)用發(fā)布到host。 ??
  37. ???????????host.fireContainerEvent(INSTALL_EVENT,?context);??
  38. ???????}? catch ?(Exception?e)?{??
  39. ???????????host.log(sm.getString( "standardHost.installError" ,?contextPath),??
  40. ????????????????????e);??
  41. ??????????? throw ? new ?IOException(e.toString());??
  42. ???????}??
  43. ??
  44. ???}??

經(jīng)過上面的代碼分析,已經(jīng)完全了解了怎么發(fā)布一個(gè)目錄型的應(yīng)用到StandardHost中,其他war包和文件描述符類型的應(yīng)用發(fā)布跟StandardHost大體類似,在這里就不說了,有興趣的可以自己查看源代碼。

Tomcat源碼分析(十)--部署器


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

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

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 亚洲狠狠搞 | 香港一级毛片在线播放 | 日韩男女做性高清在线观看 | 成人在线小视频 | 免费v片 | 三a级片| 国产黄在线观看免费观看软件视频 | 亚洲成人小视频 | 成人一区二区丝袜美腿 | 日韩精品一区二区在线观看 | 99精品99 | 日产精品乱码卡一卡2卡三 久久99精品久久久久久综合 | 日韩欧美大片 | 亚洲精品1 | 精品久久久久久久久久久 | 国产精品欧美一区二区三区 | 轻轻啪在线视频播放 | 三级黄色毛片视频 | 人人性人人性碰国产 | 五月丁香啪啪. | 国产一区二| 久久久国产精品福利免费 | 免费欧美黄色 | 超碰97最新| 国产成人在线观看免费网站 | 欧美激情视频网站 | 亚洲一区二区三区久久 | 香港三级大全 | 欧美同性精品xxxx | 久草草视频在线观看免费高清 | 久久久久亚洲精品中文字幕 | 精品久久久久久久久久久久久久 | 国产精品尤物在线 | 中文字幕a∨在线乱码免费看 | 欧美a级片视频 | 国产精品久久久久久久久久久久冷 | 男女爽爽无遮挡午夜动态图 | 九一在线观看 | 亚洲一区二区在线视频 | 国产区精品 | 91精品影视|