OSGi:简介

为基于Java的系统创建的OSGi提供了模块化系统的框架。 OSGi使得可以定义每个单独模块与其他模块的依赖关系,并使用户可以控制生命周期并动态更改系统的每个组件。

OSGi是一个规范,最常见的实现可以算作EquinoxApache FelixKnoplerfish 。 在本文中,我将尝试举一个在Equinox中创建简单OSGi捆绑包的示例。

OSGi结构

基本的OSGi结构可以在右侧的图中看到。 OSGi实现位于JVM的顶部,并提供用于模块的服务管理,组件定义,执行,管理和生命周期控制的机制。 最基本的OSGi概念描述如下:

在OSGi系统中,用于构建结构的组件的名称为“ Bundle ”。 在部署阶段,每个OSGi捆绑包都是一个jar文件。 但是bundle jar文件与常规jar文件的主要区别可以算作OSGi特定的清单定义和某些OSGi特定的类。 我们将在即将到来的部分和示例中讨论这些差异。

服务

服务提供了结构束之间的交互。 服务作为接口公开,并向执行该接口的实现注册。 与SOA结构并行,通过OSGi服务进行访问使得与基于常规jar的Java结构相比,基于OSGi的系统更加松散耦合。 这些结构还可以在运行时更改系统的更改组件。

OSGi为要注册和访问的服务实现服务目录。 OSGi还提供了服务管理机制。

生命周期

OSGi提供了一个平台,可以控制捆绑软件的生命周期。 在这种结构中,每个捆绑软件都有其自己的OSGi配置,主要是在依赖关系和暴露部分方面,并且系统由OSGi本身运行。 OSGi知道组成系统的捆绑包,该捆绑包带有一个带有顺序的配置文件,并且生命周期管理以给定顺序应用于每个组件。 生命周期管理的包端由“ Activator”类控制,该类实现了OSGi接口,该接口必须存在于每个“常规” OSGi包中。 (不适用于“片段”片段,但这已经超出了本文的讨论范围,请忽略这一点)

如上所述, b undle是一个jar文件,其中至少包含一个Activator类和一个MANIFEST文件,其中包含OSGi特定的标头和信息。下面可以看到一个示例MANIFEST文件。 让我们看一下定义中每个部分的含义。

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文件中唯一的强制性定义,符号名称定义OSGi生态系统中捆绑软件的唯一名称。 由于此定义应该唯一,因此通常按照约定将其定义为捆绑软件的基本包名称。
  • 捆绑包描述:有关捆绑包 “存在理由”的描述。
  • Bundle-ManifestVersion:捆绑包的清单版本。
  • 捆绑软件版本: OSGi捆绑软件版本。
  • Bundle-Activator:此类用于控制包的生命周期。 OSGi调用此类以启动或停止捆绑软件。
  • 导出包:本节中定义了希望由其他包使用的包。
  • Import-Package:本节中定义了执行当前包所需的包。

OSGi结构提供了必要的机制来控制束的生命周期。 捆绑软件受OSGi的控制,以根据给定的配置控制其生命周期。 此生命周期步骤将在下面详细说明:

组件状态
描述
已安装
此状态表明安装步骤已成功完成。 在这种情况下,既不进行依赖关系分析也不进行类加载。 仅执行必需的步骤,例如定义分析其清单文件的包属性。
解决
当OSGi解析并满足其所有依赖关系并进行类加载操作时,便会在此状态下找到捆绑软件。 这是启动之前和停止之后的状态。
开始
这是在调用捆绑软件的激活器的“启动”方法但尚未成功或未成功完成时找到捆绑软件的状态。
活性
该捆绑包已成功启动并正在运行,这意味着Activator的“启动”方法导致成功。
停止
这是在调用捆绑软件的激活器的“停止”方法但尚未成功或未成功完成时找到捆绑软件的状态。
未安装
这是从系统中删除捆绑软件时的状态。 在这种情况下,不会过渡到另一个状态。 必须再次安装该组件。
上图中可以看到所描述的生命周期步骤之间的过渡。

让我们做一个简单的例子来阐明上面提到的概念和步骤。 在我们的示例中,将有两个捆绑包,其中一个捆绑包提供一个随机数生成器服务以生成随机数,另一个捆绑包将使用此服务每秒打印一个随机数,并进行单独的处理。 (没有道理吗?对我来说也一样,但足以掌握概念 :)

现在,让我们使用Eclipse和Equinox一起开发此示例项目(最好)。
在Eclipse中,使用“新建插件项目”向导开发OSGi捆绑包,如下所示:

使用向导创建两个项目( us.elron.osgi.randomus.elron.osgi.user ),按照所需的步骤进行操作并按如下所示命名包和激活器( RandomActivatorUserActivator )。 该项目的最终结果也应该是这样的:

下面给出了随机数生成包( us.elron.osgi.random )的服务定义,实现和清单定义。
接口(IRandomGenerator):

package us.elron.osgi.random;public interface IRandomGenerator {int generate ();int generate(int upperBound);}

服务(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说明如下。 捆绑软件至少应导出具有其服务接口的软件包,以便其他捆绑软件使用它们。 因为松散耦合是SOA和OSGi系统的最重要目标之一,所以仅应从任何捆绑包中导出最少的必需类集。

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

可以看出,服务是注册为OSGi服务的Java接口的实现。 激活程序类是捆绑软件的OSGi访问点。 OSGi使用捆绑软件的Activator类来管理其生命周期。 在此过程中,OSGi将“ org.osgi.framework.BundleContext ”接口的实现发送到分发包。 该接口使捆绑软件可以与OSGi层进行交互,并且可以在代码中看到,从而进行诸如注册和获取OSGi服务之类的操作。
现在让我们看一下用户包类:
这是打印由随机生成器服务生成的随机数的类。

package us.elron.osgi.user;import us.elron.osgi.random.IRandomGenerator;public class RandomPrinter extends Thread {private final IRandomGenerator random;private volatile boolean run = true;public RandomPrinter (final IRandomGenerator random) {this.random = random;}@ Overridepublic void run () {while (this.run) {System.out.println ("[User] new random number: " + this.random.generate (300));try {Thread.sleep (1000);} catch (final InterruptedException e) {break;}}System.out.println ("[User] The process was terminated.");}public void close () {this.run = false;}}

这是Activator的实现:

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描述如下。 我们应该使用随机服务接口所在的随机生成器束的“ us.elron.osgi.random”包定义依赖项。 可以在包或包级别定义依赖关系,但是,为了减少包之间的依赖关系,最好尽可能地选择包级别的依赖关系。

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上运行这些项目,应定义运行配置,如下所示。 在OSGi Framework下的“ 运行 (或调试配置 ”步骤中,应创建一个新配置(右键单击),并在此配置中选择我们的新捆绑包。 要为选定的包提供所需的依赖关系,我们可以使用“添加所需的包” ”按钮。 通过这种方式,Eclipse将解决依赖关系层次结构,并为选定的依赖关系添加所需的包。 我们还应该定义捆绑包的开始顺序。 应根据捆绑包的依赖关系定义此顺序。 依赖束应在它们依赖的束之后开始。 因此,在我们的示例中,我们将“ us.elron.osgi.random”的级别设置为1 ,同时将“ us.elron.osgi.user ”的级别设置为2

以这种形状运行项目会生成如下输出:

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: 129

OSGi运行时提供了一个控制台界面供我们与自己进行交互。 运行控制台应用程序窗口时,我们看到一个“ osgi>”脚本,表示可以访问控制台。 提到您可以在控制台中执行的一些重要命令之后,我将让您一个人呆在控制台上,让您发现可以从“帮助”命令开始的操作。

“ ss”命令,显示所有注册到OSGi的组件及其ID状态捆绑包名称值以及版本部件。 id值表示OSGi给每个捆绑软件的唯一标识符。 即使重新安装并安装了捆绑软件(发现一件事),该数字在JVM执行中也保持不变,但是可以在新的执行中进行更改。 状态值指示捆绑软件的状态(在上表中详细说明), 名称版本值指示其名称对我们的影响。 对于当前系统, “ 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>

假设我们要关闭用户捆绑包。 在这种情况下,我们需要使用要停止的分发包的ID(在这种情况下为15)执行“停止”命令。

[User] a new random number is: 48
[User] a new random number is: 49
OSGi> stop 15
[User] finish ..
[User] The process was terminated.

当我们再次查看“ ss”命令的输出时,

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为15User bundle的状态已解决 (请参见生命周期部分)。 同样,我们可以执行启动命令(启动15)来启动捆绑软件并观察该过程再次开始工作,或者执行“ s ”命令查看注册到OSGi的所有服务,或者使用uninstall命令从OSGi删除捆绑软件。 您可以自由发现!

在本文中,我试图简单地解释一下OSGi是什么,它如何工作以及可以用它做什么。 希望你喜欢它。 您可以在此处下载资源

随时通过elron [at] elron.us发表评论或联系。 我很高兴收到您的来信。

参考: OSGi:我们的JCG合作伙伴 Elron在Ender Ayd?n Orak博客上的介绍。

相关文章 :

  • OSGi将Maven与Equinox结合使用
  • OSGI和Spring动态模块–简单的Hello World
  • OSGi –带有服务的简单Hello World
  • Java EE6 CDI,命名组件和限定符

翻译自: https://www.javacodegeeks.com/2012/01/osgi-introduction.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373841.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一起动手打造个人娱乐级linux

我们使用电脑,一直以来用的都是windows,但是对于像我这种爱折腾的人来说,尝试使用linux系统应该是一种不错的体验。说到linux,许多人可能都没听过,或者知道的人对它印象是这样的: 然而,linux发展…

PostgreSQL数据类型

http://blog.csdn.net/neo_liu0000/article/details/6254086 第六章 数据类型 6.1概述 PostgreSQL 提供了丰富的数据类型。用户可以使用 CREATE TYPE 命令在数据库中创建新的数据类型。PostgreSQL 的数据类型被分为四种,分别是基本数据类型、复合数据类型、域和伪类…

centos 卸载ffmpeg_CentOS Linux 操作系统安装 FFmpeg 教程

FFmpeg 是一个非常热门的开源项目,用来编解码音频视频流,被广泛用于各种流服务中。本教程在 CentOS 6、7、8 上面都可以使用,用来安装 FFmpeg 软件。一、安装前需求一个 sudo 账户,一般都是默认 root 账户即可。1、CentOS 8安装所…

Linux 火狐浏览器安装Flash插件

Linux系统安装完毕后,发现火狐浏览器视频播放不了而且总是提示安装Flash。而按火狐浏览器上的提示Flash插件安装总是失败,木有办法只能手动安装Flash插件啦。 到Flash官网:http://get.adobe.com/cn/flashplayer/ 下载系统对应的Flash插件&…

按汇总分组/多维数据集

时不时地,您会遇到一个使您达到SQL限制的要求。 我们中的许多人可能会提早放弃并使用Java / [或您的语言]计算内容。 相反,使用SQL可能是如此简单快捷。 如果您使用的是高级数据库,例如DB2 , Oracle , SQL Server &…

TCPUDP

TCP(传输控制协议) 建立连接,形成传输数据的通道在连接中进行大数据传输(数据大小不受限制)通过三次握手完成连接,是可靠协议,安全送达(三次握手向服务器发送请求,响应请求回复,发送…

Windows和linux双系统——修改默认启动顺序

电脑上装了Windows 7和Ubantu双系统,由于Linux系统用的次数比较少并且还是默认的启动项对此很不能容忍,因此得修改Windows为默认的启动项。 由于电脑上的系统引导程序是GRUB,因此修改当然也就落到Linux系统上啦。 修改/boot/grub/grub.cfg该文…

ft232h引脚_usb转串口芯片 ft232的奇怪现象

硬件平台:stm32f407ft232RL按照手册上的电路,我用USB接口给ft232RL供电,如下图:0288f358ccd0026690b2443b41d98f0f_224.png (0 Bytes, 下载次数: 12)2010-12-14 22:54 上传我在这个电路的基础上我用单片机串口和芯片对应的TX和RX相…

微软Team Foundation Service 的Scrum模板中的Feature和Backlog Items 的区别【转载】

Features help us plan work better in Team Foundation Service Scrum process 【原文:http://www.nsilverbullet.net/2013/06/04/features-help-us-plan-work-better-in-team-foundation-service-scrum-process/】 Recently a new work item type named “Featur…

LeWeb – 2011 –综述

在我去机场前几个小时,我将写最后一篇与LeWeb相关的文章。 这次,我将专注于会议本身。 参加过几次开发人员会议(虽然不多,但足以给您带来一定的经验),我已经开发了自己的自定义会议等级框架。 我使用以下6条…

Java 入门基础——面向对象的特征

计算机软件系统是现实生活中的业务在计算机中的映射,而现实生活中的业务其实就是一个个对象协作的过程。面向对象编程就是按现实业务一样的方式将程序代码按一个个对象进行组织和编写,让计算机系统能够识别和理解用对象方式组织和编写的程序代码&#xf…

(总结)密码破解之王:Ophcrack彩虹表(Rainbow Tables)原理详解(附:120G彩虹表下载)...

http://www.ha97.com/4009.html转载于:https://www.cnblogs.com/chaizp/p/5111188.html

python游走代码_介绍一个全局最优化的方法:随机游走算法(Random Walk)

1. 关于全局最优化求解全局最优化是一个非常复杂的问题,目前还没有一个通用的办法可以对任意复杂函数求解全局最优值。上一篇文章讲解了一个求解局部极小值的方法——梯度下降法。这种方法对于求解精度不高的情况是实用的,可以用局部极小值近似替代全局最…

iOS单元测试

iOS单元测试异步测试需要建立预期,因为苹果的单元测试都是同步的,测试到异步的时候建立一个预期,预期如果在规定时间(自定义)完成,代表单元测试通过。 还有 猴子测试 ,就是去github上找到猴子测…

调试JVM

在某些(极少数)情况下,您可能会遇到使JVM本身崩溃的情况。 我最近通过将ThreadGroup的名称设置为null来进行管理 。 在这些情况下,调试JVM本身很有用,这样可以更精确地定位崩溃。 这是完成此操作的步骤(它们…

javaScript DOM编程常用的方法与属性

DOM是Document Object Model文档对象模型的缩写。根据W3C DOM规范,DOM是一种与浏览器,平台,语言无关的接口,使得你可以访问页面其他的标准组件。 Node接口的特性和方法 特性/方法类型/放回类型说明nodeName String 节点的名字;根…

一:验证微信的Token

前言:申请到微信公众号的同学,可能会挺感兴趣的,毕竟微信公众号,确实是一个好东西,它提供了一个很好的平台,而且它自带有一套管理模板,对于微信公众号可以很好的管理。 但是也仅仅是很好的管理,…

三、 将DataTable 转换为List

1. 方法public static IList<T> ConvertTo<T>(DataTable table) { if (table null) { return null; } List<DataRow> rows new List<DataRow>(); foreach (DataRow row in table.Rows) { rows.Add(row); } return ConvertTo<T>(rows); }2. 调用…

ActiveMQ已准备好黄金时段

ActiveMQ项目始于2005年-在很大程度上&#xff0c;它一直是Apache Software Foundation的顶级项目。 ActiveMQ项目的目的一直是提供世界一流的企业消息传递解决方案&#xff0c;其中经纪人能够提供从支持IP的智能设备一直到企业后端的高可用性的连通性。 ActiveMQ提供跨语言客户…

r语言 adf检验_r语言中如何进行两组独立样本秩和检验

r语言中如何进行两组独立样本秩和检验​tecdat.cn安装所需的包wants <- c("coin") has <- wants %in% rownames(installed.packages()) if(any(!has)) install.packages(wants[!has])>一个样本测试set.seed(123) medH0 <- 30 DV <- sample(0:100, 20,…