中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

架構設計——OSGI規范

發布時間:2020-08-03 03:31:35 來源:網絡 閱讀:28188 作者:天山老妖S 欄目:軟件技術

架構設計——OSGI簡介

一、OSGI簡介

1、OSGI簡介

OSGI(Open Service Gateway Initiative),即開放服務網關協議,是面向Java的動態模型系統。
OSGI是指由OSGI Alliance組織制定的Java模塊化規范,OSGI規范的核心部分是一個框架,其中定義了應用程序的生命周期模式和服務注冊。基于OSGI框架定義了大量的OSGI服務:日志、配置管理,HTTP服務(運行Servlet)、XML解析、設備訪問、軟件包管理、許可管理、用戶管理、IO連接、Jini和UPnP等。
OSGI中文社區:http://www.osgi.com.cn/?
OSGI官方網站:https://www.osgi.org/
OSGI框架實現了一個優雅、完整和動態的組件模型,組件(bundle)無需重新引導可以被遠程安裝、啟動、升級和卸載。
OSGI服務平臺提供在多種網絡設備上無需重啟的動態改變構造的功能。
為了最小化耦合度和促使耦合度可管理,OSGI技術提供了一種面向服務的架構,使組件動態地發現對方。
OSGI聯盟已經開發了如HTTP服務器、配置、日志、安全、用戶管理、XML等很多公共功能標準組件接口。標準組件的兼容性插件實現可以從不同計算機服務提供商得到。
OSGi的主要職責就是為了讓開發者能夠創建動態化、模塊化的Java系統。

2、OSGI規范的組成

OSGI規范包括以下子規范:
A、Framework規范(OSGI核心,提供一個安全的可管理的Java Framework來部署可擴展的Java服務)
B、Package Admin Service規范(管理不同的Bundle之間的引用關系。當Bundle更新或者卸載時判斷是否有其它的服務正在使用當前的Bundle)
C、Start Level規范(定義了啟動和停止一個OSGi Service Platform時,不同的Bundles的啟動或者停止的先后順序)
D、Permission Admin Service規范(Bundle是否許可執行另外的Bundle的代碼)
E、URL Handlers Service規范(怎樣注冊URL Schema,如何將java.io.InputStream對象轉換為特定的Java對象)
F、Log Service規范
G、Configuration Admin Service規范
H、Device Access Specification
I、User Admin Service Specification
J、IO Connector Service Specification
K、Http Service Specification
L、Preference Service Specification
M、Wire Admin Service Specification
N、XML Parser Service Specification
O、Metatype Specification
P、Service Tracker Specification
Q、Measurment and State Specification
R、Position Specification
S、Execution Environment Specfication

3、OSGI的優點

OSGI的優勢主要表現在以下幾個方面:
A、熱插拔的插件體系結構
基于OSGI的應用程序可動態更改運行狀態和行為。在OSGI框架中,每一個組件都是可熱插拔的,因此,對某一特定的組件的修改并不會影響到容器中的所有組件,運行中的大部分組件依舊能照常工作,部署一個新的Bundle時也不需要重新啟動服務器。
B、可復用性
OSGI框架本身可復用性極強,易于構建真正面向接口的程序架構,每一個組件(Bundle)都是一個獨立可復用的單元。基于OSGI獨特的特性,進行企業開發的時候,對于新的開發,可以從企業的組件庫中精簡出可復用的模塊,量身定做新的組件,最大限度的利用了已有的資源,降低開發成本,增強企業的競爭力。
C、高效性,穩定性
OSGI是一個穩定而高效的系統。OSGI作為一個微核的系統,其核心只有為數不多的幾個JAR包。基于OSGI框架的系統的低耦合性,其結構的優勢性保證具體的某一個組件不至于影響到全局,更不會因為局部的錯誤導致全局系統的崩潰。

4、OSGI的缺點

A、每個組件(Bundle)都由單獨的類加載器加載,與一些Java EE項目中使用比較多的框架整合比較困難,如Spring MVC、Struts2等。
B、目前OSGI框架提供的管理端不夠強大,現在的管理端中僅提供了基本的組件狀態管理、日志查看等功能,像動態修改系統級別的配置(config.ini)、動態修改組件的配置(Manifest.mf)、啟動級別等功能都尚未提供。
C、采用OSGI作為規范的模塊開發、部署方式自然給現有開發人員提出了新的要求,需要學習新的基于OSGI的開發方式。

二、OSGI框架原理

1、OSGI框架簡介

OSGI框架從概念上可以分為三層:模塊層、生命周期層和服務層。
Module Layer:模塊層主要涉及包及共享的代碼;
Lifecycle Layer:生命周期層主要涉及組件的運行時生命周期管理;
Service Layer:服務層主要涉及模塊之間的交互和通信。
架構設計——OSGI規范
OSGI Framework是OSGI Service Platform規范的核心組成部分,提供了一個通用的、安全可管理的Java framework。通過OSGI Framework可以支持一種叫做組件的Service application的部署和擴展。
OSGI兼容設備可以下載并且安裝OSGI組件,也可一旦不再需要的時候刪除。組件安裝后會注冊一定數量的Services,并被由同一個Framework下的其它組件使用。
在一個動態擴展的的OSGI環境中,Framework管理組件的安裝和更新,同時也管理組件和Services之間的依賴關系。
Framework提供給組件開發者必須的資源來在Java平臺上開發,為開發的組件提供了代碼動態加載的功能, 也使得開發者開發、部署一個大規模的Services變的很容易。
其次,Framework為Java組件開發者提供了簡明一致的編程模型,簡化了開發部署的復雜性。編程模型允許開發者將自己的接口規范綁定到OSGI環境中的Service。
一個一致的編程模型幫助開發者可以應付一些可估計的危急錯誤。Framework將會運行在不同的硬件環境上,但一致的接口確保組件可以運行在一致的服務接口上。

2、模塊層

模塊層是OSGi框架中最基礎的部分。
OSGi的模塊化,是通過為Jar包添加metadata 來定義哪些類該暴露,哪些類該隱藏,其控制單元叫做組件Bundle(jar包)。?
Bundle是以jar包形式存在的一個模塊化物理單元,包含代碼、資源文件和元數據(metadata),并且jar包的物理邊界也是運行時邏輯模塊的封裝邊界。
Bundle是OSGi中的基本組件,其表現形式仍然為Java概念中傳統的Jar包。
通過META-INF目錄下的MANIFEST.MF文件對其予以進一步的定義。
通常一個MANIFEST.MF文件的內容如下:

  Manifest-Version:?1.0
    Bundle-ManifestVersion:?2
    Bundle-Name:?Util
    Bundle-SymbolicName:?com.ibm.director.la.util
    Bundle-Version:?1.0.0
    Bundle-RequiredExecutionEnvironment:?J2SE-1.5
    Import-Package:?org.osgi.framework;version="1.3.0"
    Export-Package:?com.ibm.director.la.util;uses:="org.osgi.framework"
    Bundle-ClassPath:?lib/junit.jar,

MANIFEST.MF文件存儲的實際上是Bundle的元數據。
元數據的內容可以精確的定義Bundle的各種特征,同時能更好的對Bundle進行標識同時幫助用戶對Bundle進行理解。

3、生命周期層

生命周期層在OSGi框架中屬于模塊層上面的一層,生命周期層的運作是建立在模塊層的功能之上的。
生命周期層的主要功能是控制動態安裝、開啟、關閉、更新和卸載組件。
生命周期層能夠從外部管理應用或者建立能夠自我管理的應用(或者兩者的結合),并且給了應用本身很大的動態性。?
Bundle的使用需要生命周期層的API與OSGi框架的生命周期層進行交互。

4、服務層

OSGi服務是注冊到OSGi框架中的一個Java對象。注冊的時候可以設置Service的屬性。而在獲取Service的時候可以根據屬性進行過濾。
Bundle可以通過Bundle的上下文去注冊Service或去查詢Service。

三、模塊層

1、模塊化簡介

模塊化是將一個大型系統分解為多個較小的互相協作的邏輯單元,通過強制設定模塊之間的邏輯邊界來改善系統的維護性和封裝性。
架構設計——OSGI規范
模塊(module)定義了一個邏輯邊界,模塊本身精確地控制哪些類是完全被封裝起來的,而哪些類需要暴露出來作為外部使用。開開發者可以輕松地將實現屏蔽在模塊的內部,將公共API暴露在外部。

2、OSGI模塊化與面向對象

面向對象編程中不會把所有功能都塞到同一個類。面向對象編程從問題域中發現多個事物,每個事物負責不同的功能,盡量做到高內聚和低耦合。面向對象的模塊化粒度在類級別上。
OSGi的模塊化是通過為JAR包添加metadata來定義哪些類應該暴露哪些類又隱藏在包中,其控制可見性的粒度是在組件(JAR包)層面上的。
OSGI模塊化和面向對象思想所帶來的能力都是通過控制可見性和可用性來保證高內聚和低耦合的,但粒度不同,一個是組件層面上,一個是對象層面上。

3、JAVA在模塊化方面的局限

A、底層代碼的可見性控制
Java提供了private、public、protected和package private(無修飾符)四種訪問控制級別,提供了底層的OO數據封裝特性。Packege具有分割代碼的作用,但如果包中的代碼要對包外可見,必須設置為public(protected,使用繼承)。
org.serc.helloworld.Hello.java:定義了一個接口

package org.serc.helloworld;  

public interface Hello {  
    void sayHello();  
}

org.serc.helloworld.impl.HelloImpl.java:實現了Hello接口

package org.serc.helloworld.impl;

import org.serc.helloworld.Hello;

public class HelloImpl implements Hello{
    final String helloString;

public HelloImpl(String helloString){
    this.helloString = helloString;
}

public void sayHello(){
    System.out.println(this.helloString);
}
}

org.serc.helloworld.main.Main.java文件:

package org.serc.helloworld.main;

import org.serc.helloworld.Hello;
import org.serc.helloworld.HelloImpl;

public class Main{
    final String helloString;

public static void main(String[] args){
    Hello hello = new HelloImpl(“Hello,SERC!”);
    hello.sayHello();
}

三個文件分別在不同的包中。HelloImpl實現細節不應該暴露給其它包,但從Main.java的main方法中可以看出,為了創建Hello的實例,必須引入HelloImpl類,但是HelloImpl作為接口的實現細節,不應該暴露給使用者,違反了封裝的原則。
如果不想讓HelloImpl暴露出來,需要做額外的工作保證既隱藏了實現細節,又能簡單的創建一個實現了Hello接口的實例。可以通過多種方法(比如工廠模式)來實現,但增加了與應用本身功能無關的多余工作,是Java的局限。
B、classpath的局限
在classpath中加入jar包的時候,只給出文件路徑,而jar包的版本、一致性、依賴性,無法在classpath中明確的設置或是從classpath中看出相應屬性。
classpath中的jar包是按序加載的,例如:
classpath=/servlet2.2/servlet.jar;/servlet2.3/servlet.jar, 在實際應用的過程中,Java使用servlet2.2,而不是servlet2.3。如果在大型系統中團隊分開開發時,各用各的servlet包,并且版本號不一樣,在最后將開發結果合并的時候,用的是哪個版本的servlet包就很難搞清楚。
即使classpath能注意到版本的問題,也沒法精確指出依賴。開發者需要根據提示信息增加依賴包,直到虛擬機不運行到缺包異常為止。
C、OSGI對JAVA局限的改善
OSGi中很好解決了JAVA的局限性:
包的可見性:OSGi通過引入包的可見性機制,能夠完全控制一個包中的代碼對哪些模塊可見,而不僅僅局限于無差別的可見性,從而完善了Java的代碼訪問控制機制。
包的版本:OSGi通過為包增加版本信息,可以精確控制代碼的依賴,保證代碼的版本一致性,彌補了classpath的缺點。

4、組件Bundle簡介

組件(bundle)是以jar包形式存在的一個模塊化物理單元,包含了代碼、資源文件和元數據(metadata),并且jar包的物理邊界也是運行時邏輯模塊的封裝邊界。
架構設計——OSGI規范
在標準的jar包的manifest文件中添加一些組件(bundle)的模塊化特征(metadata)后,jar包就變成了一個bundle。
bundle和普通jar包最大的區別就在于元數據。
Bundle元數據的目的在于準確描述模塊化相關的bundle特征,讓OSGi框架對bundle進行各種處理工作(比如依賴解析,強制封裝等),元數據主要有三部分:
A、可讀信息(可選)
OSGi標準定義了幾個元數據條目幫助更好地理解和使用bundle,但所有的條目都不是必須的,并且不對模塊化特性產生任何的影響,OSGi框架會完全無視可讀信息。

Bundle-Name: SERC Helloworld
Bundle-Vendor: GR, SERC
Bundle-DocURL: http://elevenframework.org
Bundle-Category: example
Bundle-Copyright: SERC  

B、bundle標識符(必須)
bundle標識符用于唯一的標識一個bundle。
早期的OSGi標準中并沒有提供標識一個已知bundle的方法,直到OSGi R4標準,“唯一bundle標識符”被提出來。為了向后兼容,Bundle-Name不能用來作為標識符,否則就會增加維護向后兼容的工作,所以使用新的manifest屬性Bundle-SymbolicName。
Bundle-SymbolicName: org.serc.helloworld
Bundle-Name是給用戶讀的,而Bundle-SymbolicName是給OSGi框架讀的,讓OSGi框架能夠唯一標識一個bundle。
只用一個Bundle-SymbolicName肯定是可以唯一標識一個bundle,但是隨著時間的推移,bundle可能會有新版本,加入版本屬性會讓bundle的信息更加準確。

Bundle-Name: SERC Helloworld
Bundle-Vendor: GR, SERC
Bundle-DocURL: http://elevenframework.org
Bundle-Category: example
Bundle-Copyright: SERC  

C、代碼可見性(必須)
代碼可見性用于定義內部與外部代碼。在JavaSE中的jar包如果放在classpath里,那么jar包對classpath下的所有程序都是可見的,并且可見性不能改變。而OSGi標準定義了如下的屬性用于描述代碼的可見性:
Bundle-ClassPath:定義了形成bundle的所有代碼所在的位置,Java 中的classpath是定義的jar包的位置,而Bundle-ClassPath屬性描述的是bundle內部類在bundle中的路徑。例如:
Bundle-ClassPath:.,other-classes/,embedded.jar
Export-Package:顯式暴露需要和其它bundle共享的代碼,每個包之間用逗號分隔,每個包可用修飾詞來修飾包的其它特征。

Export-Package: org.serc.hellworld; vendor=”SERC”,
org.serc.hellworld.impl; vendor=”Gou Rui” 

Import-Package:定義bundle所依賴的外部代碼,其格式和Export-Package相同,并且也可以使用修飾詞來修飾包。修飾詞是用來限制所依賴包的范圍的,類似過濾器,而不像Export-Package中用來聲明包的特征。例如:
Import-Package: org.serc.helloworld; vendor=”SERC”

四、生命周期層

1、生命周期層簡介

生命周期層在OSGi框架中屬于模塊層上面的一層,其運作建立在模塊層的功能之上的。生命周期層主要功能是讓開發者能夠從外部管理應用或者建立能夠自我管理的應用(或者兩者的結合),并且給應用本身很大的動態性。

2、生命周期管理簡介

一般來說,程序(或者程序的一部分)都一定服從某種生命周期。軟件的生命周期有4個典型的階段,如下:
架構設計——OSGI規范
如果正在創建一個應用,首先得安裝(install)應用;當應用的所有依賴都滿足,可以執行應用;如果應用不再需要,可以停止(stop);一段時間后,可能需要更新(update)應用的版本;最終,可能會移除(remove)應用。
通過在外部或者內部對應用進行操作,完成對應用的生命周期管理過程。對于非模塊化應用,操作是以整個應用為對象的;對于模塊化應用,可以有更細粒度(針對應用中的某個模塊)的生命周期管理。

3、OSGi bundle生命周期

要想使用組件(bundle),就得使用生命周期層的API與OSGi框架的生命周期層進行交互。
OSGi框架的核心并沒有強制使用任何特定的API交互機制(比如命令行,GUI,或者XML配置文件等),只是單純的Java API而已,開發者可以任意創造出自己想要的交互模式,保證了框架的靈活性。
在標準的Java編程中,會通過將jar包放到classpath中來使用jar包,而bundle不同。Bundle只有在被安裝(install)到一個OSGi框架的運行實例中才能用起來,并且OSGi框架支持對bundle完整的生命周期管理,并且支持這些管理操作在應用執行完成,其動態性可見一斑。
Bundle生命周期的狀態轉移圖如下:
架構設計——OSGI規范
可以通過Bundle的getState方法來獲得bundle的當前狀態。
Starting和Stopping狀態是暫態,在持續一會兒后就會自動轉移到下一個狀態,不需要轉移條件。

4、生命周期層API

生命周期層的API主要由BundleActivator、BundleContext、Bundle三個核心接口組成。
A、BundleActivator
BundleActivator讓開發者能夠捕捉bundle的start和stop事件,并對作出自定義的反應。
BundleActivator的接口定義如下:

public interface BundleActivator {
    public void start(BundleContext context) throws Exception;
    public void stop(Bundlecontext context) throws Exception;
}

如果一個類實現了BundleActivator接口,那么類就成為一個Activator。但有實現是不夠的,要讓OSGi框架知道Activator的存在。所以還需要在MANIFEST文件中添加如下一項屬性:
Bundle-Activator:org.demo.Activator
當bundle啟動(start)的時候,OSGi框架就會調用Activator的start方法,同樣的也適用與stop方法。
并不是每個bundle都需要一個activator,有時候bundle只是為了和其它bundle分享代碼,而并不需要在啟動和停止的時候做出多余的動作。是否使用BundleActivator借口,需要具體問題具體分析。
B、BundleContext
BundleContext是bundle在框架中的執行時上下文,提供了與框架進行交互的方法。
BundleContext接口中的方法主要分為兩類,一類與部署和生命周期管理相關,另一類是關于利用服務層進行bundle間交互的方法。

public interface BundleContext {
    String getProperty(String key);
    Bundle getBundle();
    Bundle installBundle(String location, InputStream input) throws BundleException;
    Bundle installBundle(String location) throws BundleException;
    Bundle getBundle(long id);
    Bundle[] getBundles();
    void addBundleListener(BundleListener listener);
    void removeBundleListener(BundleListener listener);
    void addFrameworkListener(FrameworkListener listener);
    void removeFrameworkListener(FrameworkListener listener);
}  

BundleContext接口對于與其相關的bundle來說都是唯一的執行上下文,并且只有在bundle是屬于active狀態的時候執行時上下文才是有意義的,即在start方法被調用和stop方法被調用的兩個時間點之間。如果一個bundle沒有處于active時間段,但組件的bundlecontext對象被使用,框架會拋出異常。
框架使用這個上下文對象還有一個目的就是為了bundle的安全和資源分配,所以BundleContext對象應該被當做私有對象,不應該被隨意在bundle之間傳遞。
C、Bundle
Bundle在邏輯上表示一個bundle,OSGi環境中的一個物理bundle對應一個bundle對象。bundle對象中包含了bundle的基本信息和bundle聲明周期的控制接口。
在BundleContext接口中,getBundle方法可以得到Bundle對象。
對于每個被安裝到框架中的bundle,框架都創建一個Bundle對象在邏輯上表達之。Bundle接口中定義了bundle生命周期管理的方法:

public interface Bundle {
    BundleContext getBundleContext();
    long getBundleId();
    Dictionary getHeaders();
    Dictionary getHeaders(String locale);
    String getLocation();
    int getState();
    String getSymbolicName();
    Version getVersion();
    void start(int options) throws BundleException;
    void start() throws BundleException;
    void stop(int options) throws BundleException;
    void stop() throws BundleException;
    void update(InputStream input) throws BundleException;
    void update() throws BundleException;
    void uninstall() throws BundleException;
}

大部分OSGi框架的實現都是將locatioin解釋為指向OSGi bundle的一個URL,在需要的時候就會通過URL將bundle下載到框架中來安裝使用。但OSGi標準沒有規定location的形式必須是URL,而且URL也并不是非要不可的,還可以通過輸入流(Input Stream)來安裝bundle。
bundle不能自己改變自己的狀態,比如說一個active的bundle不能stop自己,stop自己就會拋出異常。

五、服務層

1、服務簡介

服務是服務提供者和服務使用者之間的一個契約。使用者一般不關心服務實現的細節,只關心是否滿足契約(服務應該提供什么功能,滿足什么格式)。使用服務的過程包含了發現服務和達成協議的形式,需要通過服務的標志性特征來找到對應的服務。

2、OSGI服務層

服務層是OSGi框架中最上面的一層,服務層帶來了更多的動態性,并且使用了面向服務編程模型。當一個bundle發現開始使用OSGi中的一個服務后,服務可能在任何的時候改變或者是消失。
OSGi框架有一個中心化的注冊表,注冊表遵從publish-find-bind模型:
架構設計——OSGI規范
一個提供服務的bundle可以發布POJO作為服務的實體;一個使用服務的bundle可以通過注冊表找到和綁定服務。
可以通過BundleContext接口來完成服務的發布、發現、綁定,如下:

public interface BundleContext {   
    void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException;  
    void addServiceListener(ServiceListener listener);  
    void removeServiceListener(ServiceListener listener);  
    ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties);   
    ServiceRegistration registerService(String clazz, Object service, Dictionary properties);  
    ServiceRegistration[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException;  
    ServiceRegistration[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException;  
    ServiceReference getServiceReference(String clazz);  
    Object getService(ServiceReference reference);  
    boolean ungetService(ServiceReference reference);  
}

3、發布服務

為了讓其它bundle能發現服務,必須在發布服務前對其進行特征描述。服務特征包括接口的名字(可以是名字的數組),接口的實現和一個可選的java.util.Dictionary類型的元數據信息。示例如下:

String[] interfaces =  new String[]{StockListing.class.getName(), StockChart.class.getname()};  
Dictionary metadata =  new Properties();  
metadata.setProperty(“name”, “LSE”);  
metadata.setProperty(“currency”, Currency.getInstance(“GBP”));  
metadata.setProperty(“country”, “GB”);  
ServiceRegistration registration = bundleContext.registerService(interfaces, new LSE(), metadata);

上述代碼中,通過ServiceRegistration對象可以更新服務的元數據:
registration.setProperties(newMetadata);
可以直接將服務注銷:
registration.unregister();
ServiceRegistration對象不能和其它Bundles共享,因為ServiceRegistration對象和發布服務的bundle的生命周期相互依存。如果bundle已經不在框架執行環境中存在,那么ServiceRegistration對象也不應該存在。
代碼中的參數new LSE()是一個POJO,不需要實現任何OSGi類型或者使用標注,只要滿足服務約定就可以。
如果在刪除發布的服務前bundle以及停止,框架會幫助刪除服務。

4、發現服務

可以根據服務約定從注冊表中找到正確的服務。發現服務并獲得其引用的接口如下:

ServiceReference reference =  
bundleContext.getServiceReference(StockListing.class.getName());  

reference是服務對象的間接引用,不直接使用服務對象是為了將服務的使用和服務的實現進行解耦,將服務注冊表作為兩者的中間人,達到跟蹤和控制服務的目的,同時還可以在服務消失后通知使用者。
ServiceReference可以在bundle之間互享,與使用服務的bundle的生命周期無關。
在getServiceReference方法中,選擇service的默認優先級是先選擇service.rank最高的,在rank相等的情況下選擇最早在框架中注冊的。除了默認的規則,還可以在getServiceReferences中通過添加過濾參數(作為調用該方法的第二個參數)來做一些篩選。

ServiceReference[] references = 
bundleContext.getServiceReferences(StockListing.class.getName(), “(&(currency=GBP)(objectClass=org.example.StockChart))”);

匹配參數是一個字符串,字符串的格式屬于LDAP查詢格式,在RFC1960標準中有完整的描述。
字符串中等號左邊的內容是元數據(Dictionary)中的左值,通過左值對應的右值與服務的元數據進行匹配。匹配示例如下:
屬性匹配:

(name=John Smith) 
(age>=20) 
(age<=65) 

模糊匹配:
(name~=johnsmith)
通配符匹配:
(name=Jo*n*Smith*)
判斷某個屬性是否存在:
(name=)
條件與:
(&(name=John Smith)(occupation=doctor))
條件或:
(|(name~=John Smith)(name~=Smith John))
*條件非: **
(!(name=John Smith))

5、綁定和使用服務

發現服務后,使用服務之前,必須從注冊表中綁定實現的服務。

StockListing listing = 
(StockListing) bundleContext.getService(reference);

返回的POJO實例和在注冊表中注冊的實例是同一個。
每次使用getService方法的時候,注冊表會將對應服務的使用次數加1,同時會記錄誰在使用該服務。如果不想使用服務的,注銷服務。

bundleContext.ungetService(reference);  
listing = null;  

六、OSGI的實現

1、OSGI的具體實現

OSGI是OSGi Alliance組織制定的Java模塊化規范,但OSGI聯盟并沒有給出OSGI容器的實現,具體實現由第三方廠商完成,目前使用較多的OSGI容器有Apache Felix、Equinox、Spring DM。

2、OSGI的JAVA實現

A、Apache Felix
Apache Felix是Apache旗下的一個OSGi框架,Felix是一個OSGi版本4規范的Apache實現。Apache Felix提供的服務幾乎涵蓋了全部的OSGi 4.2的標準,除此之外還提供了一些非標準的功能,例如iPOJO。Apache Felix框架本身非常緊湊,只需要3個包加一個shell就可以運行,無論是開發還是Debug都非常簡便。
B、Equinox
Equinox是Eclipse旗下的OSGi框架,本身也被Eclipse采用,是Eclipse的PDE開發環境的底層。Equinox本身也是相當的全面的框架,提供的功能不比Felix少多少。Equinox被當做開發Eclipse Plugin的應用較多,如果要開發一個Web程序,就會感到功能和文檔不夠全面。Equinox最大的優勢在于和Eclipse結合緊密,只要安裝了PDE,就已經有了Equinox,可以方便的在Eclipse里設置開發的Bundle,啟動、部署等操作也異常簡單,而且有專門的Debug界面。
C、Spring DM
Spring DM是Spring旗下的OSGi框架,Spring DM的最大特點是結合了Spring框架。
D、Knopflerfish
Knopflerfish是OSGi的先行者,是一個相當標準OSGi框架,提供了絕大多數標準功能。

3、OSGI的C++實現

A、CTK Plugin Framework
CTK是基于Qt開發的支持生物醫學影像計算的開源項目。
CTK中的CTK Plugin Framework模塊借鑒了OSGI的思想,并實現了幾乎完整的OSGI框架API。
B、C++ Micro Services
C++ Micro Services是基于OSGI思想的用于創建和管理模塊化軟件系統的C++庫。

4、OSGI的C實現

Apache Celix是基于C/C++的OSGI規范實現,提供了一個使用組件和面向服務編程(SOP)開發模塊化應用的框架。
Apache Celix主要使用C語言開發,為了支持C++,以庫的形式增加了抽象。
官方網站:http://celix.apache.org/

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

辽源市| 海盐县| 新邵县| 高邮市| 京山县| 古田县| 上虞市| 西乌珠穆沁旗| 宜兴市| 滕州市| 武强县| 特克斯县| 韶山市| 出国| 南宁市| 伽师县| 浙江省| 双桥区| 宜兰县| 上饶市| 石屏县| 章丘市| 安陆市| 德江县| 关岭| 金山区| 磐石市| 普格县| 南投县| 阿勒泰市| 黔东| 梨树县| 博湖县| 裕民县| 澄江县| 霸州市| 伊宁市| 桂平市| 泰宁县| 泽州县| 台中市|