OSGi:简介
OSGi是一個(gè)規(guī)范,最常見的實(shí)現(xiàn)可以算作Equinox , Apache Felix和Knoplerfish 。 在本文中,我將嘗試舉一個(gè)在Equinox中創(chuàng)建簡單OSGi捆綁包的示例。
OSGi結(jié)構(gòu)
基本的OSGi結(jié)構(gòu)可以在右側(cè)的圖中看到。 OSGi實(shí)現(xiàn)位于JVM的頂部,并提供用于模塊的服務(wù)管理,組件定義,執(zhí)行,管理和生命周期控制的機(jī)制。 最基本的OSGi概念描述如下:
束
在OSGi系統(tǒng)中,用于構(gòu)建結(jié)構(gòu)的組件的名稱為“ Bundle ”。 在部署階段,每個(gè)OSGi捆綁包都是一個(gè)jar文件。 但是bundle jar文件與常規(guī)jar文件的主要區(qū)別可以算作OSGi特定的清單定義和某些OSGi特定的類。 我們將在即將到來的部分和示例中討論這些差異。
服務(wù)
服務(wù)提供了結(jié)構(gòu)束之間的交互。 服務(wù)作為接口公開,并向執(zhí)行該接口的實(shí)現(xiàn)注冊(cè)。 與SOA結(jié)構(gòu)并行,通過OSGi服務(wù)進(jìn)行訪問使得與基于常規(guī)jar的Java結(jié)構(gòu)相比,基于OSGi的系統(tǒng)更加松散耦合。 這些結(jié)構(gòu)還可以在運(yùn)行時(shí)更改系統(tǒng)的更改組件。
OSGi為要注冊(cè)和訪問的服務(wù)實(shí)現(xiàn)服務(wù)目錄。 OSGi還提供了服務(wù)管理機(jī)制。
生命周期
OSGi提供了一個(gè)平臺(tái),可以控制捆綁軟件的生命周期。 在這種結(jié)構(gòu)中,每個(gè)捆綁軟件都有其自己的OSGi配置,主要是在依賴關(guān)系和暴露部分方面,并且系統(tǒng)由OSGi本身運(yùn)行。 OSGi知道組成系統(tǒng)的捆綁包,該捆綁包帶有一個(gè)帶有順序的配置文件,并且生命周期管理以給定順序應(yīng)用于每個(gè)組件。 生命周期管理的包端由“ Activator”類控制,該類實(shí)現(xiàn)了OSGi接口,該接口必須存在于每個(gè)“常規(guī)” OSGi包中。 (不適用于“片段”片段,但這已經(jīng)超出了本文的討論范圍,請(qǐng)忽略這一點(diǎn))
如上所述, b undle是一個(gè)jar文件,其中至少包含一個(gè)Activator類和一個(gè)MANIFEST文件,其中包含OSGi特定的標(biāo)頭和信息。下面可以看到一個(gè)示例MANIFEST文件。 讓我們看一下定義中每個(gè)部分的含義。
Bundle-Name: Our Bundle Bundle-SymbolicName: us.elron.bundles.ours Bundle-Description: Very own bundle of ours Bundle-ManifestVersion: 1 Bundle-Version: 1.0.0 Bundle-Activator: us.elron.bundles.ours.BundleActivator Export-Package: us.elron.bundles.ours.exported; version = "1.0.0" Import-Package: us.elron.bundles.yours.exported; version = "1.3.0"- 捆綁包名稱 : 捆綁包的“吸引公眾”名稱。
- Bundle-SymbolicName:作為MANIFEST文件中唯一的強(qiáng)制性定義,符號(hào)名稱定義OSGi生態(tài)系統(tǒng)中捆綁軟件的唯一名稱。 由于此定義應(yīng)該唯一,因此通常按照約定將其定義為捆綁軟件的基本包名稱。
- 捆綁包描述:有關(guān)捆綁包 “存在理由”的描述。
- Bundle-ManifestVersion:捆綁包的清單版本。
- 捆綁軟件版本: OSGi捆綁軟件版本。
- Bundle-Activator:此類用于控制包的生命周期。 OSGi調(diào)用此類以啟動(dòng)或停止捆綁軟件。
- 導(dǎo)出包:本節(jié)中定義了希望由其他包使用的包。
- Import-Package:本節(jié)中定義了執(zhí)行當(dāng)前包所需的包。
OSGi結(jié)構(gòu)提供了必要的機(jī)制來控制束的生命周期。 捆綁軟件受OSGi的控制,以根據(jù)給定的配置控制其生命周期。 此生命周期步驟將在下面詳細(xì)說明:
| 已安裝 | 此狀態(tài)表明安裝步驟已成功完成。 在這種情況下,既不進(jìn)行依賴關(guān)系分析也不進(jìn)行類加載。 僅執(zhí)行必需的步驟,例如定義分析其清單文件的包屬性。 |
| 解決 | 當(dāng)OSGi解析并滿足其所有依賴關(guān)系并進(jìn)行類加載操作時(shí),便會(huì)在此狀態(tài)下找到捆綁軟件。 這是啟動(dòng)之前和停止之后的狀態(tài)。 |
| 開始 | 這是在調(diào)用捆綁軟件的激活器的“啟動(dòng)”方法但尚未成功或未成功完成時(shí)找到捆綁軟件的狀態(tài)。 |
| 活性 | 該捆綁包已成功啟動(dòng)并正在運(yùn)行,這意味著Activator的“啟動(dòng)”方法導(dǎo)致成功。 |
| 停止 | 這是在調(diào)用捆綁軟件的激活器的“停止”方法但尚未成功或未成功完成時(shí)找到捆綁軟件的狀態(tài)。 |
| 未安裝 | 這是從系統(tǒng)中刪除捆綁軟件時(shí)的狀態(tài)。 在這種情況下,不會(huì)過渡到另一個(gè)狀態(tài)。 必須再次安裝該組件。 |
讓我們做一個(gè)簡單的例子來闡明上面提到的概念和步驟。 在我們的示例中,將有兩個(gè)捆綁包,其中一個(gè)捆綁包提供一個(gè)隨機(jī)數(shù)生成器服務(wù)以生成隨機(jī)數(shù),另一個(gè)捆綁包將使用此服務(wù)每秒打印一個(gè)隨機(jī)數(shù),并進(jìn)行單獨(dú)的處理。 (沒有道理嗎?對(duì)我來說也一樣,但足以掌握概念 )
現(xiàn)在,讓我們使用Eclipse和Equinox一起開發(fā)此示例項(xiàng)目(最好)。
在Eclipse中,使用“新建插件項(xiàng)目”向?qū)ч_發(fā)OSGi捆綁包,如下所示:
使用向?qū)?chuàng)建兩個(gè)項(xiàng)目( us.elron.osgi.random和us.elron.osgi.user ),按照所需的步驟進(jìn)行操作 , 并按如下所示命名包和激活器( RandomActivator , UserActivator )。 該項(xiàng)目的最終結(jié)果也應(yīng)該是這樣的:
下面給出了隨機(jī)數(shù)生成包( us.elron.osgi.random )的服務(wù)定義,實(shí)現(xiàn)和清單定義。
接口(IRandomGenerator):
服務(wù)(RandomGenerator):
package us.elron.osgi.random.generator;import java.util.Random;import us.elron.osgi.random.IRandomGenerator;public class RandomGenerator implements IRandomGenerator {private final Random random;public RandomGenerator () {this.random = new Random();}@ Overridepublic int generate () {return this.random.nextInt();}@ Overridepublic int generate (final int upperBound) {return this.random.nextInt (upperBound);}}激活器(RandomActivator) :
package us.elron.osgi.random;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext;import us.elron.osgi.random.generator.RandomGenerator;public class RandomActivator implements BundleActivator {public void start(final BundleContext context) throws Exception {System.out.println("[Random] Let's 'Random'!");RandomGenerator randomGenerator = new RandomGenerator();context.registerService(IRandomGenerator.class.getName (), randomGenerator, null);System.out.println("[Random] Random services were registered.");}public void stop(final BundleContext context) throws Exception {System.out.println("[Random] Bundle is being stopped !");}}組件的MANIFEST.MF說明如下。 捆綁軟件至少應(yīng)導(dǎo)出具有其服務(wù)接口的軟件包,以便其他捆綁軟件使用它們。 因?yàn)樗缮Ⅰ詈鲜荢OA和OSGi系統(tǒng)的最重要目標(biāo)之一,所以僅應(yīng)從任何捆綁包中導(dǎo)出最少的必需類集。
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Random Bundle-SymbolicName: us.elron.osgi.random Bundle-Version: 1.0.0.qualifier Bundle-Activator: us.elron.osgi.random.RandomActivator Bundle-Vendor: ELRON.US Require-Bundle: org.eclipse.core.runtime Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Export-Package: us.elron.osgi.random 可以看出,服務(wù)是注冊(cè)為OSGi服務(wù)的Java接口的實(shí)現(xiàn)。 激活程序類是捆綁軟件的OSGi訪問點(diǎn)。 OSGi使用捆綁軟件的Activator類來管理其生命周期。 在此過程中,OSGi將“ org.osgi.framework.BundleContext ”接口的實(shí)現(xiàn)發(fā)送到分發(fā)包。 該接口使捆綁軟件可以與OSGi層進(jìn)行交互,并且可以在代碼中看到,從而進(jìn)行諸如注冊(cè)和獲取OSGi服務(wù)之類的操作。
現(xiàn)在讓我們看一下用戶包類:
這是打印由隨機(jī)生成器服務(wù)生成的隨機(jī)數(shù)的類。
這是Activator的實(shí)現(xiàn):
package us.elron.osgi.user;import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference;import us.elron.osgi.random.IRandomGenerator;public class UserActivator implements BundleActivator {private RandomPrinter randomPrinter;public void start (final BundleContext context) throws Exception {System.out.println ("[User] Here we go ..");ServiceReference randSrvRef = context.getServiceReference (IRandomGenerator.class.getName ());IRandomGenerator randService = (IRandomGenerator) context.getService (randSrvRef);if (randService == null) {throw new Exception ("[User] Error! Random service could not be found!");}this.randomPrinter = new RandomPrinter(randService);this.randomPrinter.start();}public void stop (final BundleContext bundleContext) throws Exception {System.out.println ("[User] finish ..");this.randomPrinter.close ();}}“用戶”捆綁包的MANIFEST.MF描述如下。 我們應(yīng)該使用隨機(jī)服務(wù)接口所在的隨機(jī)生成器束的“ us.elron.osgi.random”包定義依賴項(xiàng)。 可以在包或包級(jí)別定義依賴關(guān)系,但是,為了減少包之間的依賴關(guān)系,最好盡可能地選擇包級(jí)別的依賴關(guān)系。
Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: User Bundle-SymbolicName: us.elron.osgi.user Bundle-Version: 1.0.0.qualifier Bundle-Activator: us.elron.osgi.user.UserActivator Bundle-Vendor: ELRON.US Require-Bundle: org.eclipse.core.runtime Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Bundle-ActivationPolicy: lazy Import-Package: us.elron.osgi.random要使用Eclipse在OSGi上運(yùn)行這些項(xiàng)目,應(yīng)定義運(yùn)行配置,如下所示。 在OSGi Framework下的“ 運(yùn)行 (或調(diào)試 ) 配置 ”步驟中,應(yīng)創(chuàng)建一個(gè)新配置(右鍵單擊),并在此配置中選擇我們的新捆綁包。 要為選定的包提供所需的依賴關(guān)系,我們可以使用“添加所需的包” ”按鈕。 通過這種方式,Eclipse將解決依賴關(guān)系層次結(jié)構(gòu),并為選定的依賴關(guān)系添加所需的包。 我們還應(yīng)該定義捆綁包的開始順序。 應(yīng)根據(jù)捆綁包的依賴關(guān)系定義此順序。 依賴束應(yīng)在它們依賴的束之后開始。 因此,在我們的示例中,我們將“ us.elron.osgi.random”的級(jí)別設(shè)置為1 ,同時(shí)將“ us.elron.osgi.user ”的級(jí)別設(shè)置為2 。
以這種形狀運(yùn)行項(xiàng)目會(huì)生成如下輸出:
OSGi> [Random] Let's 'Random'! [Random] Random services were registered. [User] Here we go .. [User] new random number: 38 [User] new random number: 250 [User] new random number: 94 [User] new random number: 150 [User] new random number: 215 [User] new random number: 124 [User] new random number: 195 [User] new random number: 260 [User] new random number: 276 [User] new random number: 129OSGi運(yùn)行時(shí)提供了一個(gè)控制臺(tái)界面供我們與自己進(jìn)行交互。 運(yùn)行控制臺(tái)應(yīng)用程序窗口時(shí),我們看到一個(gè)“ osgi>”腳本,表示可以訪問控制臺(tái)。 提到您可以在控制臺(tái)中執(zhí)行的一些重要命令之后,我將讓您一個(gè)人呆在控制臺(tái)上,讓您發(fā)現(xiàn)可以從“幫助”命令開始的操作。
“ ss”命令,顯示所有注冊(cè)到OSGi的組件及其ID , 狀態(tài)和捆綁包名稱值以及版本部件。 id值表示OSGi給每個(gè)捆綁軟件的唯一標(biāo)識(shí)符。 即使重新安裝并安裝了捆綁軟件(發(fā)現(xiàn)一件事),該數(shù)字在JVM執(zhí)行中也保持不變,但是可以在新的執(zhí)行中進(jìn)行更改。 狀態(tài)值指示捆綁軟件的狀態(tài)(在上表中詳細(xì)說明), 名稱和版本值指示其名稱對(duì)我們的影響。 對(duì)于當(dāng)前系統(tǒng), “ ss”命令的輸出如下:
OSGi> ssFramework is launched.id State Bundle 0 ACTIVE org.eclipse.osgi_3.6.0.v20100517Fragments = 4 2 ACTIVE org.eclipse.core.jobs_3.5.0.v20100515 3 ACTIVE javax.servlet_2.5.0.v200910301333Resolved javax.transaction_1.1.1.v201006150915 4Master = 0 5 ACTIVE org.eclipse.core.runtime_3.6.0.v20100505 6 ACTIVE org.eclipse.equinox.preferences_3.3.0.v20100503 7 ACTIVE org.eclipse.osgi.services_3.2.100.v20100503 8 ACTIVE org.eclipse.core.runtime.compatibility.auth_3.2.200.v20100517 9 ACTIVE us.elron.osgi.random_1.0.0.qualifierResolved org.eclipse.core.runtime.compatibility.registry_3.3.0.v20100520 10Master = 11 11 ACTIVE org.eclipse.equinox.registry_3.5.0.v20100503Fragments = 10 12 ACTIVE org.eclipse.equinox.app_1.3.0.v20100512 13 ACTIVE org.eclipse.equinox.common_3.6.0.v20100503 14 ACTIVE org.eclipse.core.contenttype_3.4.100.v20100505 14-1235 15 ACTIVE us.elron.osgi.user_1.0.0.qualifier OSGi>假設(shè)我們要關(guān)閉用戶捆綁包。 在這種情況下,我們需要使用要停止的分發(fā)包的ID(在這種情況下為15)執(zhí)行“停止”命令。
[User] a new random number is: 48 [User] a new random number is: 49 OSGi> stop 15 [User] finish .. [User] The process was terminated.當(dāng)我們?cè)俅尾榭?strong>“ ss”命令的輸出時(shí),
Framework is launched.id State Bundle 0 ACTIVE org.eclipse.osgi_3.6.0.v20100517Fragments = 4 2 ACTIVE org.eclipse.core.jobs_3.5.0.v20100515 3 ACTIVE javax.servlet_2.5.0.v200910301333Resolved javax.transaction_1.1.1.v201006150915 4Master = 0 5 ACTIVE org.eclipse.core.runtime_3.6.0.v20100505 6 ACTIVE org.eclipse.equinox.preferences_3.3.0.v20100503 7 ACTIVE org.eclipse.osgi.services_3.2.100.v20100503 8 ACTIVE org.eclipse.core.runtime.compatibility.auth_3.2.200.v20100517 9 ACTIVE us.elron.osgi.random_1.0.0.qualifierResolved org.eclipse.core.runtime.compatibility.registry_3.3.0.v20100520 10Master = 11 11 ACTIVE org.eclipse.equinox.registry_3.5.0.v20100503 Fragments = 10 12 ACTIVE org.eclipse.equinox.app_1.3.0.v20100512 13 ACTIVE org.eclipse.equinox.common_3.6.0.v20100503 14 ACTIVE org.eclipse.core.contenttype_3.4.100.v20100505-1235 15 RESOLVED us.elron.osgi.user_1.0.0.qualifier我們看到ID為15的User bundle的狀態(tài)已解決 (請(qǐng)參見生命周期部分)。 同樣,我們可以執(zhí)行啟動(dòng)命令(啟動(dòng)15)來啟動(dòng)捆綁軟件并觀察該過程再次開始工作,或者執(zhí)行“ s ”命令查看注冊(cè)到OSGi的所有服務(wù),或者使用uninstall命令從OSGi刪除捆綁軟件。 您可以自由發(fā)現(xiàn)!
在本文中,我試圖簡單地解釋一下OSGi是什么,它如何工作以及可以用它做什么。 希望你喜歡它。 您可以在此處下載資源。
隨時(shí)通過elron [at] elron.us發(fā)表評(píng)論或聯(lián)系。 我很高興收到您的來信。
參考: OSGi:我們的JCG合作伙伴 Elron在Ender Ayd?n Orak博客上的介紹。
相關(guān)文章 :
- OSGi將Maven與Equinox結(jié)合使用
- OSGI和Spring動(dòng)態(tài)模塊–簡單的Hello World
- OSGi –帶有服務(wù)的簡單Hello World
- Java EE6 CDI,命名組件和限定符
翻譯自: https://www.javacodegeeks.com/2012/01/osgi-introduction.html
總結(jié)
- 上一篇: footnote快捷键(footnote
- 下一篇: 笔记本电脑突然关机然后开不了机(笔记本电