BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

OSGi 4.3引入了Generics与Capabilities

| 作者 Alex Blewitt 关注 4 他的粉丝 ,译者 张龙 关注 14 他的粉丝 发布于 2011年4月1日. 估计阅读时间: 8 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

在近日举办的EclipseCon 2011上,下一版的核心OSGi平台发布了最终草案,其文档将于不久之后发布。BJ Hargrave在演讲中介绍了OSGi 4.3的新特性,并且概述了它与旧版之间的差别。

泛型

意料之中的一个特性就是核心OSGi API增加了泛型支持。这样就可以通过类型安全的操作查找特定类型的服务了,从而不必进行类型转换。然而,由于OSGi需要运行在嵌入式(1.5之前)VM上,因此没法使用1.5的编译器来构建核心API。但很多人都会忽略-target jsr14这个选项,我们可以使用它编译使用了泛型的Java代码并运行在1.4兼容的JRE上。引入该选项的初衷是向JSR 14中的泛型进行迁移,但现在很多编译器都将其保留了下来。这样客户端代码(使用了-target jsr14选项在1.4下编译,或是在1.5+上编译)就可以引用服务了,如下代码所示:

// OSGi 4.2 way
// ServiceReference ref = context.getServiceReference(
//   LogService.class.getName());
// LogService log = (LogService)context.getService(ref);

// OSGi 4.3 way
ServiceReference<LogService> ref = context.getServiceReference(
  LogService.class);
LogService log = context.getService(ref);

然而,由于核心并非完全兼容于1.5,因此并没有使用其他特性(诸如枚举和注解)。

Capabilities

在OSGi环境中,传统的依赖单元要么是package依赖,要么是bundle依赖(通过Import-Package或是Require-Bundle)。虽然这些依赖对于代码没什么问题,但他们却没法很好地表达非代码的依赖。比如说,某个bundle可能需要一些内存或是Web服务器,但这两者都没法通过具体的package或是bundle来表示。

OSGi 4.3引入了通用capability的概念,它可与Require-Capability和Provide-Capability搭配使用。在解析bundle之前必须得满足必要的capability需求。其典型使用场景是用于提供OSGi的声明式服务,该服务并不会表示为package依赖,但为了能够正确解析bundle,我们还是需要它的。

此外,所需的最小版本号可以通过capability的形式展现出来:

// Old way
// Bundle-RequiredExecutionEnvironment: JavaSE-1.6

// New way
Require-Capability: osgi.ee;filter:="(&(osgi.ee="JavaSE")(version>=1.6))"

出于通用性的考量,OSGi 4.3已经不建议使用Bundle-RequiredExecutionEnvironment了(但仍然存在)。

Remote Services

OSGi Remote Services并非新特性(OSGi 4.2纲要的第13章已经对其进行了介绍),但他们已经被加到了OSGi 4.3 Core规范当中了。这样,所有的OSGi 4.3运行时都将会支持Remote Services。

适配

某些服务(如PackageAdmin)用于提供关于bundle的元信息,同时又不会使用特定类型的访问符污染bundle的接口。这样我们通常都会使用一些样板代码来确定bundle是如何连接的,或是其起始层次是什么。

简化很重要,OSGi 4.3为Bundle引入了一个adapt(类)方法。类似于Eclipse的IAdaptable平台,Bundle可以转换为已知类型。本质上,如果bundle知道如何将自身转换为给定类型,那它就会返回一个实例;如果不知道(或是没有权限),那么就会返回null。这简化了PackageAdmin和StatLevelAdmin,如下代码所示:

BundleWiring wiring = bundle.adapt(BundleWiring.class);
// wiring.getRequirements(null)
BundleStartLevel bsl = bundle.adapt(BundleStartLevel.class);
// bsl.getStartLevel()

现有的服务依然可用,但推荐普通用户使用新的adapt模式以简化实现。

Weaving

Weaving支持也得以实现,这样扩展就可以插入到其他bundle的类加载机制中了。某些运行时系统使用了该技术,尤其是那些实现了JPA或是数据库持久化存储的系统——为了创建特定于该类型的代码。凭借Weaving回调,我们可以将标准的机制插入到OSGi框架中,而之前使用的则是特定于提供商的机制。

嵌套框架遭抛弃

虽然Equinox中已经有了一个试用的实现,但嵌套框架支持(意即框架可以加载嵌套的版本)却被4.3规范所抛弃了。

但却引入了更加强大的BundleHook和ResolverHook API,这样扩展就可以创建虚拟的bundle集合,使之相互不可见。这种想法来源于之前的ServiceHook,它可以实现服务之间的隐藏。

这样就可以通过创建彼此不可见的bundle分组来模拟嵌套框架了。它已经用于实现新的Virgo region model,后者则重新实现以支持这种新模型。

其副作用是如果彼此不可见,那么它可能会在同一个框架中安装相同bundle/version的多个版本。此前,当尝试再次安装相同的bundle时会出现错误。默认情况下这是不行的,但却可以在加载框架时在属性文件中通过org.osgi.framework.bsnversion=multiple属性实现这一点。默认情况下,该属性是org.osgi.framework.bsnversion=single。

总结

新的OSGi规范会为框架引入大量有用的特性;对于那些不需要支持老框架的bundle来说,新的泛型API极具吸引力,可以促成他们的转换。嵌套框架与weaving不太可能产生直接的效果,但那些实现底层库的bundle则会通过标准的回调转换到这上面来,这会增加不同的OSGi框架之间的平台交互性。

该规范尚未正式发布,但预计会在今年Eclipse发布前发布,因为Equinox 3.7很可能会成为参考实现。

查看英文原文:OSGi 4.3 brings some Generics and Capabilities

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT