2009-12-08 313 views
46

OSGi允許通過Import-Package來確定依賴關係,它僅連接一個包(從任意包導出)和Require-Bundle,它們連接到特定命名包的導出。什麼時候應該使用Import-Package,什麼時候應該使用Require-Bundle?

在構建一個未開發的OSGi應用程序時,應該使用哪種方法來表示依賴關係?大多數軟件包都是內部的,但是對外部(開源)軟件包會有一些依賴關係。

+4

從http://eclipsesource.com/blogs/2009/07/14/why-i-cant-recommend-using-import-package/:「Look,Require-Bundle是在Eclipse中用於一段時間,主要是出於遺留原因。我們不建議再使用它。如果您想要軟件包之間的鬆散耦合,導入包更好。但是,請注意疼痛分割包可能導致的問題。「 – 2009-12-08 09:47:54

回答

45

我相信Require-Bundle是一個Eclipse的東西(現在已經在OSGi規範中使它適應Eclipse)。 「純粹的」OSGi方法是使用Import-Package,因爲它專門將軟件包從提供它的軟件包中分離出來。您應該聲明您需要的功能(Java API由特定版本的特定軟件包提供)的依賴關係,而不是來自哪些功能(這對您無關緊要)。這使捆綁的組合更加靈活。

JavaScript類比:這就像檢測Web瀏覽器是否支持某個API,而不是根據用戶代理字符串說明它是什麼類型的瀏覽器來推斷。

OSGi聯盟的Peter Kriens在OSGi blog上對此有更多的評論。

可能唯一需要使用Require-Bundle的情況是,如果您有拆分軟件包,即分佈在多個軟件包中的軟件包。拆分包當然非常不鼓勵。

+2

OSGi規範中定義了Require-Bundle和Import-Package;這兩者沒有「純」的變體。 – AlBlue 2009-12-08 19:40:42

+2

@AlBlue:更新了我的答案,使其更加清楚,雖然Require-Bundle在規範中,但它僅在Eclipse中兼容。 – Thilo 2009-12-09 00:51:09

+6

我認爲Thilo是對的。正如Peter Kriens在文章中提到的那樣:「Require-Bundle具有難以否認的直觀吸引力。」但它不必要地捆綁在一起。 在Java世界中,我會將它與IoC進行比較,並直接查找依賴關係。 一個例子取決於'commons-logging'軟件包vs取決於'commons-logging' API軟件包。在後一種情況下,您可以輕鬆地將'common-logging'軟件包與適當的SLF4J適配器軟件包進行交換,該軟件包還可以輸出commons-logging' API軟件包,從而可以無縫地創建從「commons-logging」到SLF4J的橋樑。 – 2009-12-09 06:21:21

3

我相信導入包給你鬆散耦合,應該是首選。我在聲明對不包含的包(如slf4j)的依賴性時使用它,並且可以根據需要交換實現。當依賴項是我控制的東西時,例如我自己的包,我使用Require-Bundle,因爲無論如何,任何重要的更改都會經歷我自己。

-1

我不相信使用Import-Package更好,因爲我使用bundle的默認期望是使用關聯的公共API。因此,Require-Bundle更有意義。

+5

該聲明沒有任何意義。您的理由是您將使用導入包而不是要求包的原因。處理公共API,不必擔心由誰提供。你不用捆綁工作,你使用API​​。 – Robin 2012-01-18 21:07:03

13

贊成Import-Package over Require-Bundle。

要求束:

  • 指定了明確的軟件包(和版本)使用。如果一個請求包需要重構,並且一個包需要被移植到其他地方,那麼依賴者將需要對其MANIFEST進行更改.MF
  • 可讓您訪問該包的所有導出,無論它們是什麼,無論您是否需要它們。如果零件你不需要有自己的依賴關係,你需要那些
  • 束可以再出口
  • 雖然氣餒,允許使用拆分包的,即:跨多個包
  • 傳播包
  • 可用於非代碼依賴關係,例如:資源,幫助等。

導入級封裝:

  • 更鬆散的耦合,只有包(和版本)中詳細說明,運行時找到所需的束
  • 實際實現可以swaped出
  • 從屬軟件包可以被軟件包所有者移動到不同的軟件包中
  • 但是需要更低的粒度級別來維護更多的元數據(即:每個軟件包名稱)
+0

對於導入包,如果您需要包的特定版本但包中實際包含版本,該怎麼辦? AFAIK,java包沒有版本。 – 2015-08-25 14:39:24

0

Import-Package應該會更好,因爲,正如前面說的,你可以從一個包移到一個包另一個不改變現有客戶的MANIFEST.MF

但是......

有一個實際的原因如果使用Eclipse開發捆綁軟件,請使用Require-Bundle

Eclipse不使用包作爲分辨率的單位。它使用包。也就是說,如果您使用一個包的一個包,Eclipse將編譯您的包,而不會報告使用未從該包導入的其餘包的任何問題。

你可能(你是人類)認爲一切正常,並上傳你的包進行部署,但是......你的包會在運行時中斷。

我很確定,因爲這個問題發生了(對我來說)今天。

好的解決方案是更改Eclipse類路徑容器,但是......如果這不會完成......您可以決定避免這種需要捆綁而不是軟件包的問題,​​並支付所提到的價格(捆綁之間沒有向後兼容的代碼移動)。

0

避免導入包裝。由於軟件包提供了軟件包之間的多對多關係,它們很容易產生難以檢測和避免的依賴性循環。

另一方面,Require-Bundle引用單個bundle,通過簡單的構建時間檢查使得依賴圖免受循環影響。 通過Require-Bundle,構建具有較低抽象級別的分層體系結構要容易得多。

相關問題