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

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

系統 1811 0

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

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

  1. Context?context?=? new ?StandardContext();??
  2. Host?host?=? new ?StandardHost();??
  3. host.addChild(context);??
別看這簡單,其實這就是核心的部署代碼。當然,Tomcat的部署器絕不是這么點東西,但其實也是比較簡單的東西。在Catalina的createStartDigester()方法中(具體怎么調用到這個方法,詳細參考 Tomcat源碼分析(一)--服務啟動 ),向StandardHost容器中添加了一個HostConfig的實例。HostConfig類實現了LifecycleListener接口,也就是說它是個監聽器類,能監聽到組件的生命周期事件(有關生命周期的東西請參看 ?Tomcat源碼分析(七)--單一啟動/關閉機制(生命周期) )。? 下面看接受事件的方法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)?{? //如果監聽到的事件對象類型是StandardHost就設置相關屬性。 ??
  7. ???????????????? int ?hostDebug?=?((StandardHost)?host).getDebug();??
  8. ???????????????? if ?(hostDebug?>? this .debug)?{??
  9. ???????????????????? this .debug?=?hostDebug;??
  10. ????????????????}??
  11. ????????????????setDeployXML(((StandardHost)?host).isDeployXML()); //是否發布xml文件的標識,默認為true ??
  12. ????????????????setLiveDeploy(((StandardHost)?host).getLiveDeploy()); //是否動態部署標識,默認為true ??
  13. ????????????????setUnpackWARs(((StandardHost)?host).isUnpackWARs()); //是否要將war文件解壓縮,默認為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))? //監聽到容器開始,則調用start方法,方法里面調用了部署應用的代碼 ??
  22. ????????????start();??
  23. ???????? else ? if ?(event.getType().equals(Lifecycle.STOP_EVENT))??
  24. ????????????stop();??
  25. ??
  26. ????}??
如果監聽到StandardHost容器啟動開始了,則調用start方法來,下面看start方法:

  1. protected ? void ?start()?{??
  2. ??
  3. ??????? if ?(debug?>=? 1 )??
  4. ???????????log(sm.getString( "hostConfig.start" ));??
  5. ??
  6. ??????? if ?(host.getAutoDeploy())?{??
  7. ???????????deployApps(); //發布應用 ??
  8. ???????}??
  9. ??
  10. ??????? if ?(isLiveDeploy())?{??
  11. ???????????threadStart(); //動態發布應用,因為HostConfig也實現了Runnable接口,threadStart啟動該線程來實現動態發布 ??
  12. ???????}??
  13. ??
  14. ???}??
  15. ??--------------------》deployApps方法,該方法會把webapps目錄下的所有目錄都看作成一個應用程序??
  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); //通過描述符發布應用 ??
  29. ???????deployWARs(appBase,?files); //發布war文件的應用 ??
  30. ???????deployDirectories(appBase,?files); //發布目錄型的應用 ??
  31. ??
  32. ???}??

以上三個發布應用的方式大同小異,所以只說說常用的發布方式--目錄型的應用,下面看看deployDirectories方法,只寫了關鍵的邏輯:

  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()); //得到應用的路徑,路徑的寫法是???file://應用名稱 ??
  36. ?????????????????((Deployer)?host).install(contextPath,?url);? //安裝應用到目錄下 ??
  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);會調用到StandardHost的install方法,再由StandardHost轉交給StandardHostDeployer的install方法,StandardHostDeployer是一個輔助類,幫助StandardHost來實現發布應用,它實現了Deployer接口,看它的install(URL config, URL war)方法(它有兩個install方法,分別用來發布上面不同方式的應用):

  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類型的應用 ??
  12. ???????????url?=?url.substring( 4 ,?url.length()?-? 2 );??
  13. ???????}??
  14. ??????? if ?(url.startsWith( "file://" ))//如果是目錄類型的應用??
  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得到的其實是StandardContext, ??
  25. ???????????Context?context?=?(Context)?clazz.newInstance();??
  26. ???????????context.setPath(contextPath); //設置該context的訪問路徑為contextPath,即我們的應用訪問路徑 ??
  27. ?????????????
  28. ???????????context.setDocBase(docBase); //設置該應用在磁盤的路徑 ??
  29. ??????????? if ?(context? instanceof ?Lifecycle)?{??
  30. ???????????????clazz?=?Class.forName(host.getConfigClass()); //實例化host的監聽器類,并關聯上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實例,即把context應用發布到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. ???}??

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

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


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日本免费一区二区久久人人澡 | 97久久综合精品久久久综合 | 一级做a爱片久久蜜桃 | 国产成人精品一区二区视频 | 99影视在线视频免费观看 | 国产美女a做受大片在线观看 | 国产高清视频在线免费观看 | 青青影院一区二区免费视频 | 亚洲欧美精品一区 | 2021福利视频| 久久精品一区二区影院 | 91手机在线视频观看 | 亚洲国产精品一区 | 天天艹在线 | 国产午夜不卡在线观看视频666 | 毛片天天看| 亚洲精品久久久久久动漫剧情 | 国产精品视频久久久久 | 日本三级欧美三级 | 天天干狠狠 | 亚洲第一区第二区 | 国产精品亚洲成在人线 | 欧洲亚洲一区 | 九九99久久精品在免费线bt | 久久国产精品免费网站 | 成人欧美一区二区三区在线 | 男女污污在线观看 | 成人精品视频在线 | 久操资源网 | 日本欧美一区二区三区在线观看 | xxxx成年视频免费 | 国产网红福利视频网站 | 欧美jizz18性欧美 | 性生活免费网站 | 久久精品全国免费观看国产 | 亚洲你懂的 | 亚洲国产成人精品女人久久久 | 日日撸夜夜干 | 自拍 亚洲 欧美 | 爱爱视频在线免费观看 | 天天做人人爱夜夜爽2020毛片 |