OpenDaylight中的OSGi

从写单个类的打印hello world小程序到osgi模块化开发,确实存在较大的难度,本文将从模块化、osgi模型以及osgi在opendaylight中的应用等方面进行介绍。
一、模块化
我们学习java语言时,最初写的程序便是在控制台打印hello world,此时,我们写的代码放在一个类中;慢慢地,我们编写的代码需要放在几个的类时,我们就要考虑如何设计类与类之间的关系,你需要面向对象的设计原则和模式;工作中我们要做一个小项目,就可能涉及到数百个类了,我们会根据不同的业务职责将这些类进行逻辑上的划分,分隔不同的小模块,每个小模块赋予相应的职责,也就是将一个系统分解为多个较小的互相协作的单元,并设定单元之间的边界来改善系统的维护性和封装性。大致过程如下图①②③所示:
至目前为止,我们所做的事情是对类进行了逻辑的包装,而实质上并没有对类进行物理隔离。通常情况下,软件在初始构建时,并不是很复杂,但随着时间的推移、业务特性的增加、不规范的代码调用以及为赶进度而忽略架构的设计,就使得软件变得复杂起来,甚至极难维护。如同双11爆仓时凌乱不勘的场景:
图片来自互联网
那么如何降低软件的复杂性呢?生活中的货物运输或许是一个很好的借鉴例子,我们将零散的货物打包在一起,形成封闭的空间;然后,通过标准的接口装载到集装箱运输船。
事实上,早在1972年国际软件工程大师david parnas在《on the criteria to be used in decomposing systems into modules》一文中就提出了模块化编程的思想:“每项任务构成一个独立的、特有的程序模块。实现时,每个模块及其输入/输出都有确定含义的......系统以模块化的方式进行维护”,其实质就是软件模块划分应该以基于信息隐藏为目的,以职责划分为手段,从而封装变化。联想到集装箱的例子,软件的模块可以类比为集装箱,如下图所示:
我们现在正式介绍软件模块,在《java应用架构设计 模式与osgi》一书中进行了描述:软件模块是可部署的、可管理的、原生可重用的、可组合的、无状态的软件单元,它为用户提供了简洁的接口。
① 可部署:模块是一个独立的部署单元,它能够与其他软件模块共处。ear、war以及jar文件。
② 可管理:在运行时,模块可以进行安装、卸载以及更新。实体样例:ear、war以及jar文件。
③ 原生可调用:模块总是原生可调用的。也就是说,模块暴露的操作是通过直接调用方法触发的。
④ 可组合:一般指的是粗粒度的模块是由细粒度的模块组成的。
⑤ 无状态:特定版本的模块只会存在一个实例。
由前面的分析可知,java模块化支持局限于细粒度的面向对象支持,需要有更高抽象粒度的模块。osgi便是java模块化需求其中一个解决方案。
一、osgi
什么是osgi?osgi(open services gateway initiative,开放服务网关协议)是由 1999 年成立的 osgi 联盟提出的一个开放的服务规范,最早用于嵌入式设备。在2004年,eclipse发布于基于osgi的运行时模型,把 equinox 作为底层运行平台。借助于eclipse,osgi在商业化软件企业中得到广泛的关注。现已广泛应用于移动设备、桌面应用以及企业应用服务器。
osgi框架osgi框架是应用的执行环境。osgi框架规范定义了osgi的行为,现已有apache felix、eclipse equinox以及knopflerfish等多个开源实现。osgi的分层架构如下:
模块层定义了模块,称为bundle,体现为一个jar文件,由类文件、资源文件和manifest.mf组成。和普通的jar文件唯一不同的就是manifest.mf文件的内容,基本上都是标识bundle的属性,import-package声明了请求jar文件中的代码所需要的外部包。其文件样例为:
生命周期层定义了动态安装和管理bundle,即可以在框架中安装和卸载bundle,而不需要重启应用进程。
服务层定义了面向服务的应用编程模型,涉及面向服务的发布、查找和绑定交互模式:服务提供者将服务发布到服务注册中心,然后服务请求者通过搜索服务注册中心,查找可供使用的服务。这种机制称为vm中的soa。事实上,服务就是java接口。
3.osgi生态
4.bundle交互
了解了osgi基础知识后,我们来看下bundle交互的实现方式:
(1) export和import:即通过package的export和import来进行。服务提供者bundle对外export自己的package,而服务请求者则根据业务需要import外部的package;
(2) service:服务提供者bundle对外提供service,而服务请求者查找service。而提供service的方式又有:
① 通过bundlecontext(bundle上下文)来提供和获取;
② 通过declarative service来实现;
③ 通过blueprint来实现;
在这里,我们重点介绍第3种方式--blueprint。blueprint提供一个依赖注入框架来实现osgi,并在osgi compendium r4.2里被osgi组织标准化。blueprint的强大之处在于即具有spring强大且非侵入性的企业级编程模型又具有osgi的动态性、模块化的特性。
bundle间的交互使用类似spring bean的方式配置定义,blueprint的xml文件定义和描述不同bundle的组装。一个简单的blueprint示例如下:
xml文件的命名空间标识blueprint 1.0.0版本。顶级的blueprint元素标识xml文件作为一个blueprint模块来定义;reference元素标识从osgi服务注册中心为组件获得一个服务;bean元素标识与spring bean相同的含义。
一、osgi在opendaylight中的应用
java模块化的局限和osgi框架的模块化标签,使得java和osgi走在了一起,进而增加了java模块化开发的能力。
作为sdn控制器,opendaylight使用了java语言编写,sdn控制器本身的功能与协议繁多导致了其子项目众多,如何更好地按需动态加载所需的项目成为技术选型的一个重要因素。而osgi的如下特性也使得其在opendaylight中发挥很大的作用:
① 将一个程序打包成逻辑上独立的jar文件,并且只部署那些某个安装所需要的部分。
② 将一个程序打包成逻辑中独立的jar文件,声明哪些代码可以被其他jar文件访问,并且强调可见性。
③ 为程序提供一个插件式的扩展机制。osgi模块化特别适合提供强大的扩展机制,包括支持执行时的动态性。
opendaylight采用了osgi框架之后,那开发一个应用程序的流程又是怎样的呢?下面给出一般方法:
① 根据应用的业务场景设计bundle,并设计bundle的服务;
② 使用ide实现bundle,配置blueprint容器xml文件;
③ 打包和部署bundle的jar文件;
④ 启动类似karaf之类的部署环境,并根据业务需要安装bundle。
事实上,opendaylight不仅采用了osgi框架,而且还使用了apache karaf这个企业级容器,下篇文章我们将探讨apache karaf的基础知识。

新能源汽车即将爆发,国内造车新势力不断崛起
运动耳机你还在选择传统耳机吗?骨传导耳机或许更加适合你
凯柏胶宝®将在2022 年国际橡塑展 (CHINAPLAS)亮相行业创新突破成果
Qorvo在MWC 2018期间荣获两项GTI大奖 不愧是5G领头羊
荣耀普调工资?华为手机10月暴涨93%!中国智能手机复苏步伐加速
OpenDaylight中的OSGi
iPhone XI爆料:A13仿生处理器、更大容量电池
BananaPi 开源社区完成基于Rockchip RK3588J/3588M芯片的全工规,全国产化验证
5G商用开启, 宏基站PCB市场在三年内有望达到279亿元
纳米笼催化剂保障燃料电池超长稳定运行时间
余承东回应转岗传闻:还未拼尽全身力气,岂敢先溜
三星Galaxy P30通过3C认证,搭载后置指纹识别
K30 Pro目前并未见踪影 或将在明年3月亮相
白领为何大爱航世BOW iPad Pro专用键盘?
三星note7爆炸原因暂未公布 传明年照推note8
协鑫集成发布公告称,将拟5.61亿元投资徐州睿芯电子产业基金,或将成为国家半导体产业发展的一支主力军
深度剖析110V至310V转换器电路
三星2019年利润受内存影响严重 预计二月份将推出新版手机
uc3845中文资料(uc3845引脚图及功能_特性参数及典型应用电路)
统信软件誓要打造中国操作系统创新生态