osgi简介

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

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

OSGi结构

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

在OSGi系统中,用于构建结构的组件的名称为“ Bundle ”。 在部署阶段,每个OSGi捆绑包都是一个jar文件。 但是捆绑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>”脚本,表示可以访问控制台。 提到您可以在控制台中执行的一些重要命令之后,我将让您一个人呆在控制台上,让您发现可以从“ help”命令开始的操作。

“ 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)执行“ stop”命令。

[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

osgi简介

osgi简介_OSGi:简介相关推荐

  1. OSGI中blueprint简介

    OSGI中blueprint简介 上篇博文我们开始了felix中的一个example编写,原本计划是讲felix中的几个example全部编写一遍,但是随后发现felix的这几个example都差不多 ...

  2. DriverManager 驱动管理器类简介 JDBC简介(三)

    驱动程序管理器是负责管理驱动程序的,驱动注册以后,会保存在DriverManager中的已注册列表中 后续的处理就可以对这个列表进行操作 简言之,驱动管理器,就是字面含义,主要负责就是管理 驱动 概述 ...

  3. 【Android 高性能音频】Oboe 函数库简介 ( Oboe 简介 | Oboe 特点 | Oboe 编译工具 | Oboe 相关文档 | Oboe 测试工具 )

    文章目录 一.Oboe 简介 二.Oboe 特点 三.Oboe 编译工具 四.Oboe 文档 五.Oboe 测试 一.Oboe 简介 Oboe 简介 : ① 函数库 : Oboe 是 C++ 函数库 ...

  4. 【Android 应用开发】Paint 图形组合 Xfermod 简介 ( 图形组合集合描述 | Xfermod 简介 | PorterDuff 简介 )

    文章目录 图形组合 集合描述 Xfermod 简介 PorterDuff 由来 Xfermod 合成模式分类 图形组合 集合描述 图形组合 集合描述 : 1.下面我们先描述两个集合 : ① 集合 A ...

  5. Data Source与数据库连接池简介 JDBC简介(八)

    DataSource是作为DriverManager的替代品而推出的,DataSource 对象是获取连接的首选方法. 起源 为何放弃DriverManager DriverManager负责管理驱动 ...

  6. Swagger 学习笔记 | Swagger 简介 | Springfox 简介 | Springfox 2.9.2 常用注解 | Spring Boot 整合 Swagger2 案例

    文章目录 一.Swagger 简介 二.Springfox 简介 三.Springfox2.9.2 常用注解 四.SpringBoot 整合 Swagger2 4.1 引入Maven依赖 4.2 项目 ...

  7. osgi 模块化_OSGi案例研究:模块化vert.x

    osgi 模块化 OSGi使Java代码可以清晰地划分为多个模块,这些模块称为捆绑软件 ,可以访问由每个捆绑软件的类加载器控制的代码和资源. OSGi 服务提供了一种附加的分离机制:接口的用户无需依赖 ...

  8. 【AOP 面向切面编程】AOP 简介 ( AspectJ 简介 | AspectJ 下载 )

    文章目录 一.AOP 简介 二.AspectJ 简介 三.AspectJ 下载 一.AOP 简介 AOP 是 Aspect Oriented Programming 的缩写 , 面向切面编程 ; 利用 ...

  9. 【Flutter】Flutter Gallery 官方示例简介 ( 项目简介 | 工程构建 )

    文章目录 一.Flutter Gallery 简介 二.Flutter Gallery 项目构建 发现一个很强的 Flutter 开源项目 , 由 Flutter 官方提供的 Flutter Gall ...

最新文章

  1. Java项目:(前端vue后台java微服务)在线考试系统(java+vue+springboot+mysql+maven)
  2. 学python要多少钱-Python培训一般要多少钱?
  3. 【C#】事件,委托3点详解
  4. 行为型模式:模板方法
  5. 复习计划15.4.24(待完善)
  6. Mybatis的动态创建删除表
  7. spring aop实例讲解_Spring框架核心知识点
  8. asp.net电子商务开发实战 视频 第二讲 (下)
  9. oneproxy mysql_在OneProxy的基础上实行MySQL读写分离与负载均衡
  10. 追踪电子邮件行踪的“眼”
  11. 13_展示商品的详情
  12. 一些关于coffeescript
  13. 基于Milton的webdav解决方案 - Test
  14. 回顾码农历程总结2013 期待2014
  15. 李时珍编撰《本草纲目》以《证类本草》为蓝本
  16. CVPR2019|最新更新论文~持续更新|CVPR2019百度云下载
  17. 为什么大部分服务器都用Linux系统
  18. mac 下webstorm调节字体大小
  19. 春风得意的 jQuery
  20. sftp命令上传本地文件到服务器,使用sftp命令上传文件夹方法

热门文章

  1. 用指针完成函数参数的调用
  2. 两个map中的数据,按照相同键,将所对应的值相加方法
  3. 回忆四班的那些事儿~
  4. java中如何对对象排序?
  5. Photoshop的基本操作
  6. 钟 docker讲解
  7. linux软件可以在所有发行版运行吗,Linux通用的跨发行版的3大软件包管理器
  8. xrkmonitor监控mysql_xrkmonitor字符云监控系统
  9. tomcat(supplement)HttpConnector.initialize() 和 start() 方法 以及 StandardContext.start()方法的分析
  10. java日志——修改日志管理器配置+日志本地化