日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OSGI动态加载删除Service bundle

發布時間:2025/3/21 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OSGI动态加载删除Service bundle 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

OSGi模塊化框架是很早就出來的一個插件化框架,最早Eclipse用它而出名,但這些年也沒有大熱雖然OSGi已經發布了版本1到版本5。現在用的最多的,也是本文講述基于的是Equinox的OSGi實現,同時也是Eclipse核心,Spring Dynamic Module也是基于Equinox。OSGi框架為java系統提供了一個通用的容器,該系統中的 bundle,無需停止系統,即可實現 bundle 的安裝、卸載。OSGi是Java中目前唯一的一個模塊化、動態化的規范。在模塊化方面OSGi聯盟已經研究了很多年了,因此OSGi規范對于模塊的物理隔離、模塊的交互、多版本這些方面都有了非常完善的機制,并且也得到了現在幾乎所有的App Server廠商或開源社區的認可,但至今沒有被JAVA納入語言級(有待觀察)。OSGi的突出特點有:

  • 可以動態加載、更新和卸載模塊而不用停止服務
  • 實現系統的模塊化、版本化,允許多版本bundule同時服務
  • Service model允許模塊/插件相互依賴但松耦合,分享服務更簡單

OSGi運行在JVM之上,其架構圖如下圖所示:

OSGi適用場景

很多人錯誤的使用了OSGi, 套用了OSGi架構把系統復雜化。在我看來,OSGi的用處在于“模塊化”和“熱插拔”。模塊化包括模塊化、版本化和面向服務的設計。熱插拔也就是說模塊/bundle的熱插拔,它可以實現更新和升級模塊/bundle(即系統的一部分)而無需重啟整個系統。

如果你的系統套用了OSGi架構,bundle的相互依賴關系復雜,又沒有bundle動態加載、動態更新、動態卸載和動態監聽的機制,都是靜態啟動所有bundle,那就是為了OSGi架構而OSGi架構,把問題復雜化了。其代價也是很大的,因為原來你的jar包用maven來處理依賴關系和自動更新也很方便,而由于整個系統建立在OSGi規范上,你的應用所依賴的其他組件也“不得不”遷移到OSGI上來,再加上OSGI獨特的ClassLoader設計,使bundle間的類互相訪問受到一定的約束,一切都需要遷移到OSGi的約束上來。

舉個例子來說,就像Eclipse提供了動態加載、更新和刪除插件的機制,因為它里面有一個插件注冊和反注冊的接口和插件加載、更新和刪除的監聽線程,這樣允許你動態加載、更新和刪除Eclipse插件而無需重啟Eclipse。當然,如果你當前進程調用了某插件,比如js語法高亮,而某插件更新了,那么當前的js實例還是需要重新打開的。但整個Eclispe無需重啟。

Java模塊化的難點

OSGi的一個重要特性就是模塊化,OSGi提供了一套模塊化的體系,這其中則會有明確的模塊之間接口暴露以及依賴的定義,因此能夠更好的實現高內聚和低耦合。那么,Java模塊化難點在哪?模塊的實現和傳統的編程方法確實有一些差別,主要體現在模塊之間類訪問的隔離、版本選擇這兩個方面。如希望更好的設計模塊化的系統,開發者需要掌握ClassLoader機制、模塊之間類的交互方法(這包括了模塊怎么樣對外提供可訪問的package、怎么樣訪問其他模塊提供的package、如何選擇適合版本的package等)。如果不懂以上這些,貿然套用OSGi框架會誤入歧途。

重要概念:Bundle

Bundle — A bundle is a JAR file with special OSGi entries in its manifest and containing classes, resources, and other JARs。Bundle,可以將其理解為自描述的 JAR 文件。Bundle在OSGi中是部署的最小單位,因此,可以把它理解為模塊。在 bundle 的 manifest 文件中,會有對本 bundle 的標識、提供的功能 (Export-package) 及依賴性 (Import-Package/Require-Bundle) 的定義。每個 bundle 在運行時自己的類加載器 (Class Loader),這樣可以做到一方面把不同的 bundle 里面的類區別開來,當 bundle 被卸載時,只有這個 bundle 的類加載器中的信息會丟失;另一方面,可以在自己的 bundle 內部充分利用 Java 的成員訪問控制機制。

Bundle通過MANIFEST.MF進行自描述,下面是一個例子:

1

2

3

4

5

6

7

8

9

10

Manifest-Version: 1.0

Bundle-ManifestVersion: 2

Bundle-Name: Popup Plug-in

Bundle-SymbolicName: com.example.myosgi; singleton:=true

Bundle-Version: 1.0.0

Bundle-Activator: com.example.myosgi.Activator

Require-Bundle: org.eclipse.ui,

?org.eclipse.core.runtime

Bundle-ActivationPolicy: lazy

Bundle-RequiredExecutionEnvironment: JavaSE-1.6

Bundle類隔離機制

每個Bundle均為獨立的ClassLoader,是java動態化實現的基礎。默認情況下有Boostrap classLoader (jre/lib/classes)、Extension classloader (jre/lib/ext)、 System classloader (classpath指定),應用可以自行實現classloader及動態的加載類,或加載特定目錄下的類。

?

Bundle的生命周期

Lifecycle — A lifecycle is the sequence of states a bundle goes through: uninstalled, installed, resolved, starting, stopping, active. 生命周期圖如下所示:

要注意的是:bundle狀態變為Resolved并不表示能提供服務,所以啟動所有的bundle不表示類都已經加載到內存了。Resolve bundle做以下的幾件事情:尋找bundle依賴的包是否存在以及被resolve,尋找匹配的import package,required bundle,如尋找則進入檢查,檢查沒有沖突就形成綁定關系,以便加載類的時候能直接加載(但僅僅Resolved,不代表類被加載了)。如果你的BundleActivationPolicy是LAZY惰性加載,bundle.loadClass()調用才會到達Active狀態。如果你的bundle的MANIFEST.MF中配置的Bundle-activator存在,那就調用其start方法,從starting進入active狀態。

1

2

3

4

5

osgi> ss

??"Framework is launched."

??id????? State?????? Bundle

??15??????STARTING??? com.example.serviceconsumer_1.0.0.X

??16??????RESOLVED??? com.example.serviceprovider_1.0.0.X

下面的圖更詳細的解釋了這一點:

?

OSGi Service

Service — A service is an object instance exposed under the one or more interfaces that it implements and a map of properties. 簡單來說,Service model允許每個bundle對外分享一組服務,其它的bundle都可以調用這些接口的服務。這也就是OSGi bundle之間調用的方式。Service可以用來:

  • Export functionality from a bundle to other bundles
  • Import functionality from other bundles
  • Register listeners for events from other bundles
  • Expose external devices, such as UPnP devices or even hardware, to other OSGi bundles. See the?Deviceand?UPnP?APIs
  • Expose java code running in OSGI to an external network, e.g. via the UPnP or?SOAP?protocols.
  • Bundle configuration, using the?Configuration Manager

實際做法來看,通常會把接口和實現分開。接口放到一個bundle里面。實現(service)放到另外一個bundle里面,類似下面的圖示中,bundle A和B是Service,其interface放到Bundle C:

也可以是提供一個jar包,里面定義了擴展接口,然后規定新的擴展bundle必須實現該jar包里面定義的interface。實現示意圖如下所示(OsgiCommand接口定義在擴展點jar包里面,新的bundle必須包含):

Bundle的Service之間交換方式和注冊方式:

  • 通過bundleContext.registerService注冊服務,然后通過bundleContext.getServiceReference獲取服務(不推薦)
  • 使用監聽器?listeners?
    ServiceListener?和ServiceTracker?提供bundle和service的動態監聽,ServiceTracker可以動態監聽未來的bundle和service(OSGi Release 2提供的ServiceTracker?,一般推薦)
  • 通過Declarative Service?(OSGi?DS,或者Spring Dynamic Module?(DM))的方式(OSGi Release 4開始,重點推薦!)

第二種通過ServiceTracker?來查詢或偵聽服務注冊和注銷的例子代碼:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

package?com.ibm.osg.example.mygetservice;

?

import?org.osgi.framework.BundleActivator;

import?org.osgi.framework.BundleContext;

import?org.osgi.util.tracker.ServiceTracker;

import?com.ibm.osg.example.mtservice.MyTestService;

?

public?class?MyBundleActivator

???????implements?BundleActivator, Runnable

{

??????private?boolean?done=false;

??????private?ServiceTracker testServiceTracker;

?

??????// Bundle Activator Start Method

??????public?void?start(BundleContext context)

??????{

?????????/* Here we initialize and open our ServiceTracker.

????????????It will track any service registering under

????????????the "com.ibm.osg.example.mtservice.MyTestService"

????????????interface.

?????????*/

?

???????testServiceTracker =

??????????new?ServiceTracker(context,

????????????????????????"com.ibm.osg.example.mtservice.MyTestService",

????????????????????????null);

???????testServiceTracker.open();

?

???????// Here we start a thread that will continue

???????// to use our service until

???????// the bundle is stopped.

?

???????Thread t = new?Thread(this);

???????t.setName("mygetservice thread");

???????t.start();

?

?????}

????/*Bundle Activator Stop Method -- here we stop

????the thread and close the

????ServiceTracker*/

?

????public?void?stop(BundleContext context)

????{

???????????done=true;

???????????testServiceTracker.close();

????}

????//Here is a method that uses the service

????//we are tracking.? First we get

????//the service

????//from the tracker, then we call its printMessage

????//method.

?

????public?void?useService(String message){

???????????MyTestService testService = (MyTestService)

?????????????????????????testServiceTracker.getService();

?

???????if( testService != null?)

???????{

?????????????// If the service is available then use it.

????????????????testService.printMessage(message);

???????}

???????else{

?????????????// If the service is not available then perform an acceptable action.

?????????????// Here we just print the message to standard out and indicate the service

?????????????// was not available.

?????????????System.out.println("No MyTestService available - "?+ message);

???????}

????}

?

????// Simply continues to use the test service

????// every second until the done flag is set.

????public?void?run(){

???????int?i = 0;

???????done = false;

???????while?(!done) {

??????????useService("message from test "?+ i++);

??????????try{

?????????????????????Thread.sleep(1000);

??????????}

?????????????????catch( InterruptedException ie ){

??????????}

???????}

?????}

}

?

OSGi簡單起步

從Eclipse創建OSGi的bundle是非常簡單的,簡單起步可以參考這幾篇文章:<Creating a new OSGi Bundle using Eclispe>,以前這篇。

Slideshare: OSGi理論與實戰

OSGi動態加載刪除bundle

  • 使用監聽器?listeners?
    ServiceListener?和ServiceTracker?提供bundle和service的動態監聽,ServiceTracker可以動態監聽未來的bundle和service(OSGi Release 2提供的ServiceTracker?,一般推薦)
  • 通過Declarative Service?(OSGi?DS,或者Spring Dynamic Module?(DM))的方式(OSGi Release 4開始,重點推薦!)

    具體實現:

    • 對于DS,<Define a declarative OSGi Service>, <IBM: Declaring your services to OSGi Declarative Services>,<java OSGI Declarative Services Component bundles Example>。
    • 對于Spring DM,<OSGI and Spring Dynamic Modules – Simple Hello World>, <Hello, OSGi, Part 2: Introduction to Spring Dynamic Modules>

分布式OSGi(Distributed OSGi)

OSGi容器可以包含幾千個bundlue沒有問題,但如何應對幾十萬個的情況?如何像EJB3一樣具有分布式部署和便攜性呢?有一個OSGi的子項目:分布式OSGi(Distributed OSGi)。

?

上圖是一個demo演示,兩個分布式OSGi Container,都部署了Greeter接口bundle,都基于分布式OSGi實現,能實現分布式調用OSGi Service。分布式OSGi(Distributed OSGi)還可以與RESTful Service (JAX-RS / JSR-339)整合。分布式OSGi有幾十萬個bundle怎么管理,這是個麻煩,而且如何啟動停止,啟動順序怎么樣?可管理性是個麻煩,ACE項目試圖解決這個事情。

DOSGi的原理(由Distribution provider來給OSGi Service創建Endpoint,使這些Service在OSGi Container外部可訪問,另外一端則創建代理;此外,有監聽器來偵聽OSGi Service的創建和啟停等):

分布式OSGi與ZooKeeper

ZooKeeper是Hadoop的一個子項目,它是一個針對大型分布式系統的可靠協調系統,提供的功能包括:配置維護、名字服務、分布式同步、組服務等。ZooKeeper的目標就是封裝好復雜易出錯的關鍵服務,將簡單易用的接口和性能高效、功能穩定的系統提供給用戶。

分布式OSGi(Distributed OSGi)在Discovery這一塊使用了ZooKeeper。所謂Discovery模塊就是用來發現和偵聽分布式的遠端的可用的Endpoints。Discovery Ditributed with Zookeeper的架構圖:

參考:DOSGi使用ZooKeeper server的安裝和Demo。

?

就寫到這把,具體的代碼就不放上來了,公司的項目保密要求。原理上面都講了,自己去研究吧。

from:?http://www.cnblogs.com/Mainz/p/3548396.html#

《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的OSGI动态加载删除Service bundle的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。