亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

通過ClassLoader管理組件依賴(圖)

2019-11-18 11:58:39
字體:
來源:轉載
供稿:網友

  java的類加載機制是非常強大的。你可以利用外部第三方的組件而不需要頭文件或靜態連接。你只需要簡單的把組件的JAR文件放到classpath下的目錄中。運行時引用完全是動態處理的。但假如這些第三方組件有自己的依靠關系時會怎么樣呢?通常這需要開發人員自己解決所有需要的相應版本的組件集,并且確認他們被加到classpath中。
  
  JAR清單文件
  
  實際上你不需要這樣做,Java的類加載機制可以更優雅地解決這個問題。一種方案是需要每一個組件的作者在JAR清單中定義內部組件的依靠關系。這里清單是指一個被包含在JAR中的定義文件元數據的文本文件(META-INF/MANIFEST.MF)。最常用的屬性是Main-Class,定義了通過java –jar方式定位哪個類會被調用。然而,還有一個不那么有名的屬性Class-Path可以用來定義他所依靠的其他JAR。Java缺省的ClassLoader會檢查這些屬性并且自動附加這些特定的依靠到classpath中。
  
  讓我們來看一個例子??紤]一個實現交通模擬的Java應用,他由三個JAR組成:
  
  ·simulator-ui.jar:基于Swing的視圖來顯示模擬的過程。
  ·simulator.jar:用來表示模擬狀態的數據對象和實現模擬的控制類。
  ·rule-engine.jar:常用的第三方規則引擎被用來建立模擬規則的模型。
  simulator-ui.jar依靠simulator.jar,而simulator.jar依靠rule-engine.jar。
  
  而通常執行這個應用的方法如下:
  $ java -classpath
  simulator-ui.jar:simulator.jar:rule-engine.jar
  com.oreilly.simulator.ui.Main
  
  編者注:上面的命令行應該在同一行鍵入;只是由于網頁布局的限制看起來似乎是多行。
  
  但我們也可以在JAR的清單文件中定義這些信息,simulator-ui的MANIFEST.MF如下:
  
  Main-Class: com.oreilly.simulator.ui.Main
  Class-Path: simulator.jar
  
  而simulator的MANIFEST.MF包含:
  Class-Path: rule-engine.jar
  
  rule-engine.jar或者沒有清單文件,或者清單文件為空。
  
  現在我們可以這樣做:
  $ java -jar simulator-ui.jar
  
  Java會自動解析清單的入口來取得主類及修改classpath,甚至可以確定simulator-ui.jar的路徑和解釋所有與這個路徑相關的Class-Path屬性,所以我們可以簡單按照下面的方式之一來做:
  $ java -jar ../simulator-ui.jar
  $ java -jar /home/don/build/simulator-ui.jar
  
  依靠沖突
  
  Java的Class-Path屬性的實現相對于手工定義整個classpath是一個大的改善。然而,兩種方式都有自己的限制。一個重要的限制就是你只能加載組件的一個特定版本。這看起來是很顯然的因為許多編程環境都有這個限制。但是在大的包含多個第三方依靠的多JAR項目中依靠沖突是很常見的。
  
  例如,你正在開發一個通過查詢多個搜索引擎并比較他們的結果的搜索引擎。Google和Amazon的Alexa都支持使用SOAP作為通訊機制的網絡服務API,也都提供了相應的Java類庫方便訪問這些API。讓我們假設你的JAR- metasearch.jar,依靠于google.jar和amazon.jar,而他們都依靠于公共的soap.jar。
  
  現在是沒有問題,但假如將來SOAP協議或API發生改變時會怎么樣呢?很可能這兩個搜索引擎不會選擇同時升級??赡茉谀骋惶炷阍L問Amazon時需要SOAP1.x版本而訪問Google時需要SOAP2.x版本,而這兩個版本的SOAP并不能在同一個進程空間中共存。在這里,我們可能包含下面的JAR依靠:
  
  $ cat metasearch/META-INF/MANIFEST.MF
  Main-Class: com.onjava.metasearch.Main
  Class-Path: google.jar amazon.jar
  
  $ cat amazon/META-INF/MANIFEST.MF
  Class-Path: soap-v1.jar
  
  $ cat google/META-INF/MANIFEST.MF
  Class-Path: soap-v2.jar
  
  上面正確地描述了依靠關系,但這里并沒有包含什么魔法--這樣設置并不會像我們期望地那樣工作。假如soap-v1.jar和soap-v2.jar定義了許多相同的類,我們肯定這是會出問題的。
  $ java -jar metasearch.jar
  SOAP v1: remotely invoking searchAmazon
  SOAP v1: remotely invoking searchGoogle
  
  你可以看到,soap-v1.jar被首先加在classpath中,因此實際上也只有他會被使用。上面的例子等價于:
  $ java -classpath
  metasearch.jar:amazon.jar:google.jar:soap-v1.jar:soap-v2.jar
  # WRONG!
  
  編者注:上面的命令行應該在同一行鍵入;只是由于網頁布局的限制看起來似乎是多行。
  
  有趣的是假如Yahoo也發布了一個網絡服務API,而他看起來并沒有依靠于現有的SOAP/xml-RPC類庫。在較小的項目中,組件依靠沖突常被用來作為在你只要手工包裝方案或者只需要一兩個類時而不使用讓你不使用全量組件(如集合類庫)的原因之一。手工包裝方案有他的用處,但使用已有的組件是更普遍的方式。而且復制其他組件的類到你的代碼庫永遠不是一個好主意。實際上你已經與組件的開發產生分岐而且沒有機會在有問題修復或安全升級時合并他。
  
  許多大的項目,如主要的商業組件,已經采用將他們使用的整個組件構建到他們的JAR內部。為了這么做,他們改變了包名使其唯一(如com/acme/Foobar/org/freeware/utility),而且直接在他們的JAR中包含類。這樣做的好處是可以防止在這些組件中多個版本的沖突,但這也是有代價的。這么做對開發人員來說完全隱藏了對第三方的依靠。但假如這種方式大規模的應用,將會導致效率的降低(包括JAR文件的大小和加載多個JAR版本到進程中的效率降低)。這種方式的問題在于假如兩個組件依靠于同一個版本的第三方組件時,就沒有協調機制來確定共享的組件只被加載一次。這個問題我們會在下一節進行研究。除了效率的降低外,很可能你這種綁定第三方軟件的方式會與那些軟件的許可協議沖突。
  
  另一種解決這個問題的方式是每一個組件的開發人員顯式的在他的包名中編碼一個版本號。Sun的javac代碼就采用這個方式—一個com.sun.tools.javac.Main類會簡單地轉發給com.sun.tools.javac.v8.Maino。每次一個新的Java版本發布,這個代碼的包名就改變一次。這就答應一個組件的多個發布版本可以共存在同一個類加載器中并且這使得版本的選擇是顯式的。但這也不是一個非常好的解決方案,因為或者客戶需要準確知道他們計劃使用的版本而且必須改變他們的代碼來轉換到新的版本,或者他們必須依靠于一個包裝類來轉發方案調用給最新的版本(在這種情況下,這些包裝類就會承受我們上面提到的相同問題)。
  
  加載多個發布版本
  
  這里我們碰到的問題在大多數項目中也存在,所有的類都會被加載到一個全局命名空間。假如每一個組件有自己的命名空間而且他會加載所有他依靠的組件到這個命名空間而不影響進程的其他部分,那又會怎么樣呢?實際上我們可以在Java中這么做!類名不需要是唯一的,只要類名和其所對應的ClassLoader的組合是唯一的就可以了。這意味著ClassLoader類似于命名空間,而假如我們可以加載每一個組件在自己的ClassLoader中,他就可以控制如何滿足依靠。他可以代理類定位給其他的包含他的依靠組件所需要的特定版本的ClassLoader。如圖1。
  
 通過ClassLoader治理組件依靠(圖)(圖一)
  Figure 1. Decentralized class loaders

  
  然而這個架構并不比綁定每一個依靠的JAR在自己的JAR中好多少。我們需要的是一個可以確保每一個組件版本僅被一個類加載器加載的中心集權。圖2中的架構可以確定每一個組件版本僅被加載一次。
  
 通過ClassLoader治理組件依靠(圖)(圖二)
  Figure 2. Class loaders with mediator

  
  為了實現這種方式,我們需要創建兩個不同類型的類加載器。每一個ComponentClassLoader需要擴展Java的URLClassLoader來提供需要的邏輯來從一個JAR中獲取.class文件。當然他也會執行兩個其他的任務。在創建的時候,他會獲取JAR清單文件并定位一個新屬性Restricted-Class-Path。不像Sun提供的Class-Path屬性,這個屬性暗示特定的JAR應該只對這個組件有效。
  public class ComponentClassLoader extends URLClassLoader {
  // ... public ComponentClassLoader (MasterClassLoader master, File file)
  {
  // ...  JarFile jar = new JarFile(file);
  Manifest man = jar.getManifest();
  Attributes attr = man.getMainAttributes();
  List l = new ArrayList();
  String str = attr.getValue("Restricted-Class-Path");
  if (str != null) {
  StringTokenizer tok = new StringTokenizer(str);
  while (tok.hasMoreTokens()) {
  l.add(new File(file.getParentFile(),
  tok.nextToken());
  }
  }
  this.dependencies = l;
  } public Class loadClass (String name, boolean resolve)
  throws ClassNotFoundException {
  try {
  // Try to load the class from our JAR.
  return loadClassForComponent(name, resolve);
  } catch (ClassNotFoundException ex) {}
  // Couldn't find it -- let the master look for it
  // in another components.
  return master.loadClassForComponent(name,
  resolve, dependencies);
  }
  public Class loadClassForComponent (String name,
  boolean resolve)
  throws ClassNotFoundException
  {
  C

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩欧美在线免费| 亚洲男人天堂九九视频| 欧美性猛交xxxx免费看| 亚洲精品98久久久久久中文字幕| 亚洲一区二区中文字幕| 亚洲精品久久视频| 热久久免费国产视频| 宅男66日本亚洲欧美视频| 成人黄色在线免费| 国产综合色香蕉精品| 色综合久久中文字幕综合网小说| 亚洲无线码在线一区观看| 日韩欧美中文字幕在线播放| 久久久久久久久久久久久久久久久久av| 日本欧美精品在线| 精品中文字幕在线2019| 亚洲精品免费网站| 95av在线视频| 欧美激情精品久久久久久久变态| 欧美一区三区三区高中清蜜桃| 久久躁日日躁aaaaxxxx| 成人免费淫片视频软件| 久久久久北条麻妃免费看| 欧美亚洲另类制服自拍| 亚洲少妇中文在线| 全亚洲最色的网站在线观看| 色综合视频一区中文字幕| 亚洲国内精品视频| 日韩成人中文电影| 国产精自产拍久久久久久蜜| 色噜噜国产精品视频一区二区| 欧美日韩中文字幕日韩欧美| 亚洲国产精久久久久久| 亚洲新中文字幕| 国产成人精品在线| 亚洲xxxx在线| 97久久精品人人澡人人爽缅北| 亚洲在线视频福利| 亚洲开心激情网| 日韩av影视综合网| 亚洲精品综合久久中文字幕| 久久久久久亚洲精品中文字幕| 亚洲精品v天堂中文字幕| 欧美激情精品久久久久久蜜臀| 亚洲激情久久久| 欧美一区深夜视频| 国产视频久久久久久久| 久久精视频免费在线久久完整在线看| 日韩第一页在线| 国产精品视频精品视频| 欧美性猛交xxxx乱大交| 午夜免费日韩视频| 日韩美女av在线免费观看| 日本三级韩国三级久久| 欧美亚洲另类视频| 日韩成人黄色av| 亚洲无限av看| 亚洲国模精品私拍| 日韩hd视频在线观看| 日本久久久久久久久久久| 中文字幕亚洲自拍| 国产一区二区激情| 欧日韩不卡在线视频| www.亚洲一区| 国产日韩在线精品av| 欧美高清视频在线播放| 色播久久人人爽人人爽人人片视av| 中文字幕亚洲一区二区三区五十路| 亚洲精品国产美女| 国产精品久久久久久久久久ktv| 国产精品最新在线观看| 中文字幕日韩在线观看| 在线观看国产精品91| 日韩电影在线观看永久视频免费网站| 国产亚洲成精品久久| 91视频国产一区| 97精品久久久中文字幕免费| 色午夜这里只有精品| 欧美日韩电影在线观看| 欧美成人一区二区三区电影| 亚洲欧美激情在线视频| 成人精品在线观看| 最近2019年中文视频免费在线观看| 国产成人一区三区| 中文字幕日韩综合av| 中文字幕亚洲二区| 亚洲精品视频免费| 久久久成人精品视频| 国产精品白嫩初高中害羞小美女| 日韩中文字幕av| 日韩中文字幕在线视频播放| 丝袜亚洲另类欧美重口| 精品伊人久久97| 91亚洲永久免费精品| www.日韩系列| 成人黄色免费网站在线观看| 最近中文字幕mv在线一区二区三区四区| 18一19gay欧美视频网站| 激情亚洲一区二区三区四区| 久久亚洲精品小早川怜子66| 亚洲精品视频免费| 日韩av免费一区| 亚洲国产精品999| 亚洲国产另类 国产精品国产免费| 国产精品爱久久久久久久| 亚洲精品久久久久久久久久久久| 中日韩午夜理伦电影免费| 国产精品日韩电影| 最近中文字幕mv在线一区二区三区四区| 中文字幕在线日韩| 亚洲欧美国产另类| 欧美黑人xxx| 久久久99免费视频| 成人久久久久久久| 欧美大尺度电影在线观看| 美女撒尿一区二区三区| 26uuu另类亚洲欧美日本老年| 91精品在线一区| 91chinesevideo永久地址| 91在线高清视频| 国产精品午夜视频| 日韩一区av在线| 国模精品视频一区二区| 美日韩精品视频免费看| 欧美日韩一区二区在线| 久久久久久久国产| 国产69精品久久久久久| 91在线精品视频| 国产美女久久久| 亚洲精品国产品国语在线| 亚洲嫩模很污视频| 日韩av免费看网站| 91精品国产高清久久久久久| 日韩美女毛茸茸| 亚洲欧美国产日韩中文字幕| 亚洲欧洲日本专区| 精品国产一区二区三区在线观看| 欧美激情久久久久| 久久精品国产一区二区电影| 精品一区二区电影| 国产精品旅馆在线| 91丝袜美腿美女视频网站| 久久久久久97| 九九热这里只有精品免费看| 91av在线国产| 日韩久久精品电影| 亚洲国产精品久久久久| 九九热这里只有在线精品视| 日韩亚洲欧美成人| 国内揄拍国内精品少妇国语| 国产精品视频中文字幕91| 日韩免费观看在线观看| 久久精品中文字幕电影| 亚洲国产天堂久久国产91| 91超碰中文字幕久久精品| 日av在线播放中文不卡| 日韩视频永久免费观看| 日韩欧美在线观看| 17婷婷久久www| 国产精品老女人视频| 国产91在线播放九色快色| 国产69精品久久久久9| 91免费欧美精品| 欧美成人免费在线观看|