模块化Java:声明式模块化[Java编程]
本文“模块化Java:声明式模块化[Java编程]”是由七道奇为您精心收集,来源于网络转载,文章版权归文章作者所有,本站不对其观点以及内容做任何评价,请读者自行判断,以下是其具体内容:
前一篇文章,《模块化Java: 动态模块化》描写了若何通过利用服务 (service)给利用程序带来动态模块化特点.它们是通过输出的一个(或多个 )可以在运行时被动态发现的接口而实现的.固然这种方法使得client和server 完好解耦,但是又带来一个若何(什么时刻)启动服务的问题.
启动次序
在彻彻底底的动态系统里,服务不但可以在系统运行的时刻装卸,还可以以 差别的次序启动.有时,这是个大问题:无论A和B的启动次序若何,在系统到达 就绪状况并预备好接纳事件之前,假如没有事件(或线程)呈现,那么哪个服务 先启动都无大碍.
但是,有很多情形都不符合这一简单假定.经典的例子就是logging: 普通, 服务在启动和做其他操作的时刻,就要衔接并开始写日记了.假如日记服务此时 还不可用,那会有什么后果?
假定服务在运行时可以动态装卸,client应当可以应对服务不存在时的情形 .在这种情形下,它大概能聪明地转移到另一种机制(如输出到尺度输出),或 者处于阻塞状况等候服务可用(对logging系统来说不是好的答案).但是,让 服务启动之前便可用是不实在际的.
启动级别
OSGi供应了一种机制来掌握bundle启动时的次序,即便用启动级别(start levels).这一概念是基于UNIX运行级别的概念:系统以级别1启动,然后单调 递增,直到到达目标启动级别.每个OSGi容器都供应了差别的默许目标级别: Equinox默许值是6;而Felix是1.
启动级别可被用来成立bundle间的启动次序,让关键bundle服务(比方 logging)的启动级别比那些需求用它的bundle更低.但是因为可 用的启动级别 值是有限的,并且安装程序偏向于挑选单一数字作为启动级别,因此它并不能确 保你仅通过启动次序就可以办理问题.
另一点值得注意的是,具有相同启动级别的bundle是各自独立启动的(大概 并行),因此,假如你有一个与log服务具有相同启动级别的bundle,谁也不能 保证log服务可以在需求的时刻已经就绪.换句话说,启动级别可以办理大部份 问题,但不能办理全部问题.
声明式服务
办理这一问题的一个筹划是OSGi的声明式服务(以下称为DS——declarative services).用这一办法,各个组件是由外部bundle将他们组织在一同并决意他 们什么时刻可用.声明式服务是通过在一个XML配置文件组织在一同的,文件中 描写了需求(消费)或供应什么服务.
在上篇文章最后一个例子中,我们利用ServiceTracker去得到服务,假如必 要则需等候服务可用.假如我们把成立shorten号令耽误到shortening服务可用 之后会很有效.
DS定义了一个组件(component)概念,其是比bundle更细粒度的概念,但是 比服务的概念粒度更大一些(因为一个组件可以消费/供应多个服务).每个组 件都有一个名字,对应一个Java类,并可以通过调用该类的办法使其激活或失效 .与OSGi Java API差别,DS答应用纯Java POJO来开辟组件,根本不需求从程序 上依靠OSGi.其附带的好处是让DS越发易于测试和模拟(test/mock).
为了阐明这一办法,我们将持续利用前面的例子.我们需求两个组件:一个 是shortening服务本身,另一个是调用它的ShortenComand.
第一项任务是用DS配置并注册shorten服务.我们可以让DS在服务启动时注册 它,而不是通过Bundle-Activator注册该服务.
那么DS怎么知道要激活并衔接谁呢?我们需求给Bundle的Manifest头增添一 个条目,其指导了一个(或多个)XML组件定义文件.
Bundle-ManifestVersion: 2
...
Service-Component: OSGI-INF/shorten-tinyurl.xml [, ...]*
这个 OSGI-INF/shorten-tinyurl.xml组件定义文件内容以下:
<?xml version="1.0" encoding="UTF-8"?>
<scr:component name="shorten-tinyurl" xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0">
<implementation class="com.infoq.shorten.tinyurl.TinyURL"/>
<service>
<provide interface="com.infoq.shorten.IShorten"/>
</service>
</scr:component>
当DS处理这一组件时,其效果与代码context.registerService( com.infoq.shorten.IShorten.class.getName(), new com.infoq.shorten.tinyurl.TinyURL(), null );基本一样.Trim()服务需求类 似的声明,在下面的源代码中包含着这部份内容.
假如需求的话,一个单一组件可以基于差别接口供应多个服务.一个bundle 也可以包含多个组件,利用相同或差别的类,每个都供应差别的服务.
以上是“模块化Java:声明式模块化[Java编程]”的内容,如果你对以上该文章内容感兴趣,你可以看看七道奇为您推荐以下文章:
本文地址: | 与您的QQ/BBS好友分享! |