2009-12-04 104 views
8

從捆綁上下文中檢索到OSGi服務的實例後,它會在服務停止時失效嗎?OSGi中的服務引用

我的初始測試表明服務實例可以在服務包停止後使用,這與我對OSGi動態特性的理解相矛盾。

我想這可歸結爲從OSGi容器中的另一個包檢索服務(通過ServiceTracker)實際上是否會創建一個新實例,或者是否爲您提供了一個指向容器中註冊的實例的指針?

服務停止後使用服務實例是否存在危險?

回答

5

這是一個非常好的問題,所以我深入瞭解規範以尋求明確的答案。事實證明,有一整節討論這個問題 - 見5.4陳舊參考文獻OSGi Service Platform Core Specification, Release 4, Version 4.2的第132頁開始。

要根據規範回答你的問題:

服務,使之成爲未註冊的行爲是不確定的。此類服務 可能會繼續正常工作或者自行決定拋出異常。

並防止潛在的問題:

捆綁一定要聽由框架來清理和刪除過時 引用生成的事件。

該規範還提供了一些提示,以便如何最小化陳舊引用的後果。

+0

感謝,遺憾的是沒有一個明確的是或否爲我所希望的! – 2009-12-07 09:54:05

2

你說得對,因爲它與OSGi的動態特性相矛盾。我相信不能保證服務可用,儘管OSGi容器和服務的不同實現本身可能會有不同的表現。

例如,如果服務是使用Spring DM創建和註冊的,那麼檢索到的服務實際上是基於Spring的代理,並且實現仍然可以消失。因此,直接引用實現的服務引用可能會阻止該對象被刪除,而基於代理的引用則不會。

1

OSGi規範說:

軟件包是指在正常的應用程序編程可見 實體。例如,對於 示例,當一個包被停止時,所有 其服務都將被取消註冊。

因此,您應該無法從已停止的捆綁包中獲得服務。但從技術上講,使用它可能是可能的,至少只要你持有對服務對象的引用(沒有人可以將它從你身上拿走並且它不會被GC'd)。但我不認爲這是使用該服務的保存。它可能依賴於其他捆綁資源,捆綁停止後不可用。

0

關於您的問題服務停止後使用服務實例是否危險。引用4.2核心規範(5.4舊過的參考文獻):

未註冊成爲 的服務的行爲未定義。這樣的 服務可能會繼續正常工作 或在其 自行決定時拋出異常。

我不想在這裏引證規範的整段,但下面的語句是關於使用陳舊引用的危險商量好了:

一個陳舊的參考是一個Java參考對象,該對象屬於 ,該對象已停止或與未註冊的服務對象關聯 。標準Java不提供任何通用方法來清除陳舊引用,並且開發人員必須仔細分析其代碼以確保刪除舊陳舊 引用。

陳舊的引用可能是有害的,因爲它們阻止Java垃圾收集器收集停止的分組的類和可能的實例 。這可能會導致內存使用量顯着增加,並可能導致更新本機代碼庫失敗。強烈建議使用 服務的套件使用服務跟蹤器或 聲明式服務。

1

一旦OSGi服務的實例 從包上下文檢索並 當服務 停止它變得無效?

不,參考本身不會失效。只要容器內的東西持有它,它也不能被GC'ed。

但是,它是否仍然有用,僅取決於服務實現本身,而不取決於容器。

我最初的測試表明服務實例可以在服務bundle>停止後使用,這與我對OSGi動態特性的理解相矛盾。

規範本身表明不應該保留這樣的引用,但是由實施者負責照顧正確實施規範;意味着沒有矛盾,只有這樣的事實,即您可以實施和部署不符合規範的行爲正確的捆綁包。

我想這歸結爲什麼從另一個bundle 在OSGi容器檢索服務(通過ServiceTracker的)實際上呢,它創建一個新的實例,或者它會給你一個指針 到是實例在容器中註冊?

容器不會創建新的服務實例,除非涉及到ServiceFactory(請參閱規範)。查找服務應該總是給你一個指向容器中已註冊實例的指針。

服務停止後使用服務實例是否存在危險?

這隻取決於服務的實現;但是,通過這樣做,你會自動創建一個不符合規格的包。

實際上,許多服務都是爲了釋放資源和引用而實現的,並且不再適當地響應。

0

永遠不要將服務引用保留爲引用。您應該始終在運行時查找服務。這將你與OSGI api聯繫起來,然而,這並不總是想要的。

看一看 - OSGI ServiceTracker的 - OSGI聲明式服務 - OSGI藍圖 - 春天DM - 公豆 - iPojo

所有照顧活力的你,大多沒有OSGI api使用。

問候,

利恩Toelen的答案