本文主要是介绍OSGI的基本概念[自己的理解],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
OSGI ,是一种规范,目前最新版本是R4版本,这个规范的目的是为了使java系统具有更好模块化,动态性,热插拔性能。
OSGI一个很重要的应用就是与Eclipse的结合,在Eclipse3.0之后,Eclipse的插件体系完全基于OSGI,所以在我们平时的应用中,完全可以感受到OSGI这种技术给我们带给的方便之处。
随着java系统对模块化,动态性需求的增加,OSGI的应用会越来广泛。
OSGI作为一种规范,目前实现OSGI这种规范的框架有很多种,比如Equinox,Felix,Spring-DM,Knopfierfish等,应用最广泛的要数Eclipse 实现的OSGI框架 Equinox以及Apache的Felix.
OSGI中提出了一个概念叫做bundle,可以理解除了系统runtime以外,系统的其它各个功能都可以做为一个独立的bundle. 这样一个复杂的系统就可以看作一系列bundle的集合,就像搭积木一样,需要哪个功能就开发哪个bundle,做好后添加到OSGI框架中即可。
每个bundle间物理上都是隔离的,bundle中的类和接口很多时候需要隐藏,如何做到?OSGI会为每个bundle创建一个类加载器,它负责加载模块自己包含的 Java 包和类。
但是bundle之间有时会相互调用,比如bundleA可能会用到bundleB中某些服务,这时就需要一种机制使bundle间能够进行交互,实现交互的方式有两种,一种是通过在bundle的配置文件中以Import/Export的方式,另外一种是通过service的方式。
第一种方式,只需要在bundle的配置文件MANIFEST中定义这样的Header,
Import-Package:......
Export-Package:......
即可说明本bundle要引用 包和向外暴露以供其它bundle使用的包。
第二种Service的方式。
又分为两种方式
a.通过BundleContext的方式
BundleContext是在bundle启动时,OSGI框架会给每个bundle分配一个bundleContext,同时bundleContext也是 bundle与OSGI框架进行交互的纽带。
一般情况下,如果某个bundleA要向OSGI环境中注册它的一个服务,就会在bundleA的activator中将它的service(一般 就是实现了某个接口的类)的名称,以及这个类的一个实例和一些无关紧要的参数 通过调用
bundleContext.registerService(..., .... ,....) 来注册这个服务,这样等于把这某个类的一个实例注册了,其它bundle要 用这个服务时,就不用再实例化,直接得到这个实例,然后调用所需要的方法即可。
同时,如果某个bundleB想要调用这个服务,也会在bundleB的activator中通过
ServiceReference sr = (bundleContext).getServiceReference(服务名)
来获得所需服务的引用,接着通过
HttpServie http = (HttpService) bundleContext.getService(sr);
即可获得一个HttpService的实例 http.
此时就可以对这个实例进行操作了.
这种方法是OSGI中的经典做法,但是存在一些缺点,在此不细讲。
OSGI r4版本中新增加了Declarative Service的方式,使得OSGI的模块化,及动态性功能更加强大。
b.通过Declarative Service的方式
Declarative Service是SOCM(Service-oriented Component Model)模型的一种实现。
这种方式中出现了新的名词component, DS方式中,将bundle进一步细化,每个component就是一个类,
按我自己的定义,可分为生产者component以及消费者component,即服务的提供者、引用者。
怎么表明我这个bundle中使用了Declarative Service的方式?
在bundle的配置文件MANIFEST中可以定义这样的header
" Service-Component: OSGI-INF/component.xml "
就说明使用了DS的方式。
DS的比bundleContext方式进步在哪里?
DS方式中所有的服务提供以及服务引用都写在配置文件component.xml中,当bundle加载到OSGI环境中时,OSGI框 架会自动去解析这些component.xml,
如果是一个生产者component,则不会理你,等要引用其中服务的消费者component被加载时,才会去激活这个生产者 component,这样就会节省一部分资源,也就是延迟加载的意思。
如果是一个消费者component.xml,当你加载到OSGI环境中时,你的component.xml就会被解析,如果所需的服务都 已经满足,这时就可以根据component.xml中指定的bind,unbind方法,来绑定服务了,同时会激活这个component 了。
【因为component像bundle一样有自己的生命周期,这里不细讲】
可参考http://www.ibm.com/developerworks/cn/opensource/os-ecl-osgids.
最近又发现OSGi中有许多的设计模式.哪天总结了再写出来.
这篇关于OSGI的基本概念[自己的理解]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!