OSGi 基本原理
定义
这个框架实现了一个优雅、完整和动态地组价模型。应用程序(称为bundle)无序重新引导可以被远程安装、启动、升级和卸载。
为了最小化耦合度和促使这些耦合度可管理,OSGi技术提供一种面向服务的架构,它能使这些组件动态地发现对方。
OSGi联盟已经开发了例如像HTTP服务器、配置、日志、安全、用户管理、XML等很多公共功能标准组件接口。这些组件的兼容性插件实现可以从进行了不同优化和使用代价的不同计算机服务提供商得到。然而,服务接口能够基于专有权基础上开发。
OSGi的主要职责就是为了让开发者能够创建动态化、模块化的Java系统。
OSGi 框架
OSGi框架从概念上可以分为三层:模块层、生命周期层和服务层。
- Module Layer:模块层主要涉及包及共享的代码;
- Lifecycle Layer:生命周期层主要涉及Bundle的运行时生命周期管理;
- Service Layer:服务层主要涉及模块之间的交互和通信。

模块层
模块层是 OSGi 框架中最基础的部分。
OSGi 的模块化,是通过为 Jar 包添加metadata 来定义哪些类该暴露,哪些类该隐藏,其控制单元叫做 Bundle(jar 包)。
Bundle
首先,必须先了解一个基本概念——什么是Bundle?
什么是 Bundle ?

如何定义 Bundle
通常一个 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进行理解。
生命周期层
生命周期层让你能够从外部管理应用或者建立能够自我管理的应用(或者两者的结合),并且给了应用本身很大的动态性。
前面已经了解了 Bundle 的概念和作用。但是要真正使用 Bundle,需要使用生命周期层的API,来和OSGi框架的生命周期层进行交互。
下图为 Bundle 生命周期的状态转移图:

重要接口
- BundleActivator:让你能够捕捉bundle的start和stop事件,并对这两个事件作出自定义的反应。
- BundleContext:一个bundle在框架中的执行时上下文,这个上下文提供了和框架进行交互的方法。
- Bundle:在逻辑上表示了一个bundle,OSGi环境中的一个物理bundle对应了一个bundle对象。该对象中包含了bundle的基本信息和bundle生命周期的控制接口。
服务层
一个OSGi 服务就是注册到 OSGi 框架中的一个 Java 对象。注册的时候可以设置这个 Service 的属性。而在获取 Service的时候可以根据属性进行过滤。
Bundle 可以通过 Bundle的上下文去注册Service或去查询Service。
一个提供服务的bundle可以发布POJO作为服务的实体;一个使用服务的bundle可以通过这个注册表找到和绑定服务。
发布服务
例
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);
registration.setProperties(newMetadata);
也可以直接就把这个服务移除:
registration.unregister();
需要注意的是这个对象不能和其他 Bundle 共享,因为它和发布服务的bundle的生命周期相互依存。
也就是说,如果这个 Bundle 已经不在框架执行环境中存在,那么这个对象也不应该存在了,“皮之不存毛将焉附”就是这个道理。
试想如果这个 ServiceRegistration 共享给了其他的 bundle(具体的说就是其他bundle中存在对这个对象的引用),那么发布服务的那个bundle即使被移除了,由于其他bundle中的引用依然存在,那么垃圾处理机制不会抹去这个对象,这样不但于理不合,而且实际上这个对象也是不可用的,因为这个对象所依存的bundle已经不在了。
代码中的参数new LSE()是一个POJO,这个对象不需要实现任何OSGi类型或者使用标注,只要满足服务约定(这里就是接口)就可以了。
此外,如果在删除发布的服务之前bundle停止了,框架会帮助你删除这些服务。
发现和绑定服务
ServiceReference reference =
bundleContext.getServiceReference(StockListing.class.getName());
注意这里的reference是服务对象的间接引用,可是为什么要用间接引用而不直接返回那个实际的服务对象呢?
实际上是为了将服务的使用和服务的实现进行解耦,将服务注册表作为两者的中间人,达到跟踪和控制服务的目的,同时还可以在服务消失了以后通知使用者。
这个方法的返回类型是ServiceReference,它可以在bundle之间互享,因为它和使用服务的bundle的生命周期无关。
参考资料
OSGi 基本原理的更多相关文章
- OSGI中的service依赖关系管理
众所周知.对于高动态高可扩展的应用,OSGI是一个很好的平台.可是.也因此添加了复杂性.开发中对service的依赖变得复杂. 这也是service的关系管理成为OSGI中一个很重要的部分,我们来看看 ...
- OSGi规范的C#实现开源
这是大约在3-4年前完成的一个C#实现的OSGi框架,实现的过程参照了OSGi规范与与一些实现思路(感谢当时的那些资料与项目),此框架虽然仅在几个小型项目有过实际的应用,但OSGi的规范实现还是相对比 ...
- Ognl表达式基本原理和使用方法
Ognl表达式基本原理和使用方法 1.Ognl表达式语言 1.1.概述 OGNL表达式 OGNL是Object Graphic Navigation Language(对象图导航语言)的缩写,他是一个 ...
- 分享在Linux下使用OSGi.NET插件框架快速实现一个分布式服务集群的方法
在这篇文章我分享了如何使用分层与模块化的方法来设计一个分布式服务集群.这个分布式服务集群是基于DynamicProxy.WCF和OSGi.NET插件框架实现的.我将从设计思路.目标和实现三方面来描述. ...
- Android自定义控件之基本原理
前言: 在日常的Android开发中会经常和控件打交道,有时Android提供的控件未必能满足业务的需求,这个时候就需要我们实现自定义一些控件,今天先大致了解一下自定义控件的要求和实现的基本原理. 自 ...
- 重新诠释的OSGi规范
上周五部门开会讨论新一代产品(基于.net Winform)的设计规范,从设计规范慢慢讨论到体系结构等架构存在的问题,诸如菜单.工具条.状态条.界面布局等不能实现配置化和自动化,子系统之间拥有强依赖, ...
- HMM基本原理及其实现(隐马尔科夫模型)
HMM(隐马尔科夫模型)基本原理及其实现 HMM基本原理 Markov链:如果一个过程的“将来”仅依赖“现在”而不依赖“过去”,则此过程具有马尔可夫性,或称此过程为马尔可夫过程.马尔可夫链是时间和状态 ...
- 动态令牌-(OTP,HOTP,TOTP)-基本原理
名词解释和基本介绍 OTP 是 One-Time Password的简写,表示一次性密码. HOTP 是HMAC-based One-Time Password的简写,表示基于HMAC算法加密的一次性 ...
- ZooKeeper基本原理
ZooKeeper简介 ZooKeeper是一个开放源码的分布式应用程序协调服务,它包含一个简单的原语集,分布式应用程序可以基于它实现同步服务,配置维护和命名服务等. ZooKeeper设计目的 1. ...
随机推荐
- Linux下服务器端开发流程及相关工具介绍(C++)
去年刚毕业来公司后,做为新人,发现很多东西都没有文档,各种工具和地址都是口口相传的,而且很多时候都是不知道有哪些工具可以使用,所以当时就想把自己接触到的这些东西记录下来,为后来者提供参考,相当于一个路 ...
- Python列表去重
标题有语病,其实是这样的: 假设有两个列表 : L1 = [1,2,3,4] ; L2 = [1,2,5,6] 然后去掉L1中包含的L2的元素 直接这样当然是不行的: def removeExists ...
- Ubuntu 16.10 安装byzanz截取动态效果图工具
1.了解byzanz截取动态效果图工具 byzanz能制作文件小,清晰的GIF动态效果图,不足就是,目前只能通过输入命令方式来录制. byzanz主要的参数选项有: -d, --duration=SE ...
- 卡片抽奖插件 CardShow
这个小项目(卡片秀)是一个卡片抽奖特效插件,用开源项目这样的词语让我多少有些羞愧,毕竟作为一个涉世未深的小伙子,用项目的标准衡量还有很大差距.不过该案例采用 jQuery 插件方式编写,提供配置参数并 ...
- redis 学习笔记(2)
redis-cluster 简介 redis-cluster是一个分布式.容错的redis实现,redis-cluster通过将各个单独的redis实例通过特定的协议连接到一起实现了分布式.集群化的目 ...
- WPF 普通属性变化通知
问题描述:使用ObservableCollection<OrderItem> source 给Datagrid.ItemsSource赋值,在后台更新source集合后,前台Datagri ...
- 【Java大系】Java快速教程
感谢原作者:Vamei 出处:http://www.cnblogs.com/vamei Java是面向对象语言.这门语言其实相当年轻,于1995年才出现,由Sun公司出品.James Gosling领 ...
- CentOS 7 安装出现 /dev/root does not exits 导致无法安装的问题
本人在官网下的是这个 CentOS-7-x86_64-DVD-1611.iso ,然后用UltraISO 9.6制作的U盘启动盘,不过在安装的时候出现了这个错误, 然后也是搜了好久,试了一下,下面这个 ...
- hibernate5.2需要的最少jar文件
hibernate5.2需要的最少jar文件: required文件夹中的所有jar文件 + mysql-connector-java-bin.jar.
- python安装BeautifulSoup注意事项
好久没有写爬虫了,最近用Python的BeautifulSoup4.Scrapy分别对以前写的spider进行优化,发现python3.5后这些库变化了很多,遇到了许多问题,在这里做一下总结. 切换环 ...