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发展…

Linux 火狐浏览器安装Flash插件

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

按汇总分组/多维数据集

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

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

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

调试JVM

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

ActiveMQ已准备好黄金时段

ActiveMQ项目始于2005年-在很大程度上,它一直是Apache Software Foundation的顶级项目。 ActiveMQ项目的目的一直是提供世界一流的企业消息传递解决方案,其中经纪人能够提供从支持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,…

MyEclipse 8.5安装Aptana

Aptana简介 Aptana是一个非常强大,开源,专注于JavaScript的Ajax开发IDE它的特性包括&#xff1a; 1、JavaScript,JavaScript函数,HTML,CSS语言的Code Assist功能 2、Outliner(大纲)&#xff1a;显示JavaScript,HTML和CSS的代码结构 3、支持 JavaScript&#xff0c…

2016-1-10 手势解锁demo的实现

一&#xff1a;实现自定义view&#xff0c;在.h,.m文件中代码如下: #import <UIKit/UIKit.h> class ZLLockView; protocol ZLLockViewDelegate <NSObject> - (void)lockView:(ZLLockView *)lockView didSelectedPwd: (NSString *)pwd; end interface ZLLockView : …

GWT入门

GWT是Google Web Development Kit的缩写&#xff0c;可让程序员使用Java开发Ajax Web应用程序。 GWT编译器将Java代码转换为JavaScript和html代码。 GWT应用程序称为模块&#xff0c;并且使用xml文件描述模块&#xff0c;假定该模块名称为xml文件的“ mymodule”名称为“ mymod…

AJAX入门——工作原理

理解同步交互和异步交互 举个例子&#xff1a;普通B/S模式(同步) AJAX技术(异步) * 同步&#xff1a; 提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事。 发送方发出数据后&#xff0c;等接收方发回响应以后才发下一个数据包的…

Android Studio IDE Out of Memory

场景&#xff1a; 尝试过各种方式&#xff0c;IDE重装&#xff0c;重新启动&#xff0c;设置IDE MEMORY大小JDK MEMORY大小都无效 终于在FILE->INVALIDATE CACHES/RESTART 中点击重新启动之后问题攻克了。转载于:https://www.cnblogs.com/yxwkf/p/5128094.html

在Spring MVC REST应用程序中自动生成WADL

上一次我们学习了WADL的基础知识 。 语言本身并没有那么有趣&#xff0c;只写了一篇有关它的文章&#xff0c;但是本文的标题揭示了为什么我们需要这些知识。 JSR 311的许多实现&#xff1a;JAX-RS&#xff1a;RESTful Web服务的Java API提供了开箱即用的运行时WADL生成&#x…

关于DJANGO和JAVASCRIPT的时间

最近&#xff0c;实际一些简单统计时&#xff0c;要到库里去检索数据出来用HIGHCHARTS画图&#xff0c; 作一个简单的回照。。 DJANGO用TEMPLATEVIEW来作。专业&#xff0c;正规&#xff1a;&#xff09; class SAView(TemplateView):template_name version/sa_site.htmlpagin…

Vue.js组件学习

组件可以扩展HTML元素&#xff0c;封装可重用的HTML代码&#xff0c;我们可以将组件看作自定义的HTML元素。组件系统提供了一种抽象&#xff0c;让我们可以使用独立可复用的小组件来构建大型应用。 一个简单组件例子(全局注册&#xff09; <!DOCTYPE html> <html>&…

Winform MD5

1&#xff1a;MD5 http://www.cmd5.com/ 字节数组----字符串 //将字节数组中每个元素按照指定的编码格式解析成字符串//直接将数组ToString()//将字节数组中的每个元素ToString() //ToString("Params") ToString("x") //可以将十进制字符串转换为16进制字符…

HTML元素显示与隐藏

在WEB开发中&#xff0c;前台HTML中经常需要控制元素的隐藏与显示&#xff0c;我们最为最常见是二级导航栏&#xff08;通过鼠标的移动来触发onmouseover&#xff0c;onmouseout事件来实现二级菜单的显示与隐藏&#xff09;二级菜单的显示与隐藏。 然而控制元素的影响与显示有…

C#控件大小随窗体大小等比例变化

相信很多博友在开发初次接触学习C# winForm时&#xff0c;当窗体大小变化时&#xff0c;窗体内的控件并没有随着窗体的变化而变化&#xff0c;最近因为一个项目工程的原因&#xff0c;也需要解决这个问题。通过查阅和学习&#xff0c;这个问题得到了解决&#xff0c;或许不是很…

公共样式_设计干货 | 园路铺装的100种样式,保存收好

Part 1园路的形式主干道&#xff1a;联系全园&#xff0c;必须考虑通行、生产、救护、消防、游览的需要。次干道&#xff1a;沟通各景点、建筑&#xff0c;通轻型车辆。休闲小径、健康步道&#xff1a;健康步道是近年来最为流行的足底按摩健身方式。通过行走卵石路上按摩足底穴…

22个所见即所得在线 Web 编辑器

新闻来源:sixrevisions.com我们曾介绍过 10 个基于 JavaScript 的 WYSIWYG&#xff08;所见即所得&#xff09; 编辑器&#xff0c;这些 Web 编辑器可以在线编辑和处理富 Web 内容&#xff0c;包括格式文本&#xff0c;表格&#xff0c;图片&#xff0c;媒体&#xff0c;链接等…