使用 Blueprint Container 规范构建 OSGi 应用程序.doc_第1页
使用 Blueprint Container 规范构建 OSGi 应用程序.doc_第2页
使用 Blueprint Container 规范构建 OSGi 应用程序.doc_第3页
使用 Blueprint Container 规范构建 OSGi 应用程序.doc_第4页
使用 Blueprint Container 规范构建 OSGi 应用程序.doc_第5页
已阅读5页,还剩16页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

使用 Blueprint Container 规范构建 OSGi 应用程序 简介:Open Service Gateway initiative (OSGi) Alliance 框架变得越来越受欢迎。它为开发模块化的动态应用程序提供了良好的机制。最新发布的 OSGi Service Platform Release 4 V4.2 规范引入了 Blueprint Container 规范。在本文中,了解在不复杂化 Java 代码的情况下,Blueprint Container 如何为在 OSGi 环境中创建动态应用程序提供简单的编程模型。本文提供了大量示例帮助您开始使用 Blueprint XML 文件和组件 XML 定义。标记本文! 简介OSGi 框架为开发模块化的动态应用程序提供了良好的机制,它最近正变得十分流行。最新的 OSGi Service Platform Release 4 V4.2 规范包括了一个名为 Blueprint Container 的规范。Spring 动态模块如果熟悉 Spring 框架的话,您将注意到 Spring 和 Blueprint Container 规范之间有许多相似点。Blueprint 规范的基础恰好是 Spring Dynamic Modules 项目。Blueprint Container 规范为 OSGi 定义了一个依赖性注入(dependency injection)框架。它的目的是处理 OSGi 的动态特性,即服务可以在任何时间变得可用和不可用。该规范的另一个意图是处理普通旧 Java 对象(POJO),这样相同的对象就可以用于 OSGi 框架的内部和外部。定义并描述应用程序各个组件的 Blueprint XML 文件对 Blueprint 编程模型十分重要。规范描述了组件如何被实例化,以及如何相互连接在一起形成一个可以运行的应用程序。Blueprint Container 规范使用了一个扩展器(extender)模式,借助这种模式,扩展器包监视框架中的包的状态,并根据这些包的状态为它们执行操作。Blueprint 扩展器包等待包被激活,然后检查它们是否是 Blueprint 包。如果一个包包含一个或多个 Blueprint XML 文件,那么它就被认为是 Blueprint 包。这些 XML 文件位于一个 OSGI-INF/blueprint/ 目录下的某个固定位置,或者在Bundle-Blueprint清单头部中显式指定。一旦扩展器确定某个包是 Blueprint 包后,它将为这个包创建一个 Blueprint Container。这个 Blueprint Container 负责完成以下操作: 解析 Blueprint XML 文件 实例化 将组件连接在一起在初始化期间,Blueprint Container 确保强制服务引用得到满足,将所有服务注册到服务注册表中,然后创建初始的组件实例。Blueprint 扩展器包还在包停止后为该包销毁 Blueprint Container。本文将关注 Blueprint XML。通过若干示例展示组件 XML 定义及其使用。回页首Blueprint XMLBlueprint XML文件被标识为顶级blueprint元素,如清单 1 所示。清单 1. Blueprint XML 文件片段 .Blueprint XML 文件包含各种组件管理器的定义。Blueprint Container 规范定义了四种主要的组件管理器:一个bean manager、一个service manager和两个service reference managers。每种管理器都负责创建和管理所创建组件的生命周期。管理器提供了一个组件实例。每个管理器都拥有相应的 XML 元素,用于描述管理器属性。管理器可以是顶级管理器,或者内联在其他管理器定义内。管理器还具有一些通用的属性。id定义管理器的 ID。id属性是可选属性。如果没有指定的话,将自动生成一个唯一 ID 并分配给顶级管理器。内联管理器被认为是匿名的,因此不允许设置id属性。管理器 ID 在 Blueprint Container 内对于所有顶级管理器必须是唯一的。管理器使用 ID 彼此引用。例如,在注入期间,管理器将要求被引用的管理器提供对象,该对象将被注入到管理器正在创建的组件中。activation这个可选属性为管理器定义激活模式。可支持两种激活模式: eager,其中管理器在 Blueprint Container 初始化期间激活。 lazy,其中管理器按需要激活。默认情况下,启用eager激活模式。然而,通过对blueprint元素设置default-activation属性,可以为 Blueprint XML 文件内的所有管理器修改默认激活模式。当要求管理器提供其第一个组件实例时,管理器将被激活。当 Blueprint Container 被销毁时,管理器将被解除激活。每个管理器都拥有自己的激活和解除激活步骤。dependsOn这个可选属性指定了一个管理器 ID 列表。所列出的管理器将在其他管理器之前激活。管理器可以具有显式或隐式的依赖关系。dependsOn属性定义了显式的依赖关系。隐式依赖关系在管理器定义中通过对其他管理器的引用定义。回页首Bean 管理器bean 管理器创建具有给定参数和属性的 Java 对象的实例。bean 管理器可以根据范围设置创建一个或多个对象实例。它还可以管理对象的生命周期,并且在所有属性被注入或对象被销毁时通知对象。在 Blueprint XML 中,bean元素将定义一个 bean 管理器。用于对象构造的参数由argument元素指定;注入的属性则由property子元素指定。签名解析(disambiguation)Blueprint 规范定义了一个分多个步骤的算法,用于解析签名。此算法考虑所有可能的构造函数以及每个构造函数中的参数组合,从而找到最佳匹配。相同的算法被用于方法中。规范的 121.9.1 小节介绍了详细内容。在对象构造期间,Blueprint Container 必须首先找到合适的构造函数或工厂方法,这个构造函数或工厂方法具有一组类似的参数,这些参数与 XML 中指定的参数匹配。默认情况下,Blueprint Container 使用 XML 中的argument元素的数量和顺序查找匹配的构造函数或方法。如果argument元素无法根据自身的排列顺序映射到参数,那么 Blueprint Container 将尝试重新对argument属性排序并查找最匹配的组合。为了帮助 Blueprint Container 选择合适的构造函数、方法或参数组合,可以在argument元素中指定额外的属性,例如index或type。例如,type指定了一个列名,用于根据精确的类型将argument元素匹配到参数。property元素指定要注入的属性的名称和值。属性名与 Java 类中的 setter 方法名对应。例如,如果属性名为foo,那么对应的 setter 方法为setFoo(arg)。属性名和对应的 setter 方法名遵循 JavaBeans 规范中定义的属性设计模式。argument和property元素的值可以通过value或ref属性指定,或者可以被内联。ref属性指定顶级管理器的 ID,并用于从引用管理器获得对象,作为参数或属性值。内联的值可以为 “Object values” 小节中描述的任意 XML 值。构建bean 可以通过以下内容以三种方式构建: 一个类构造函数 一个静态工厂方法 一个实例工厂方法清单 2、3 和 4 演示了三种构建 Java 对象的方法。每一个清单展示一个不完整的 Java 类以及用于驱动对象创建的相应的 Blueprint XML 片段。清单 2 展示了一个简单的构造器创建示例。在这个例子中,class属性指定将要实例化的 Java 类的名称。Blueprint Container 将创建Account对象,方式为将1作为参数传递给构造器并调用setDescription()方法注入描述属性。清单 2. 构造器示例 public class Account public Account(long number) . public void setDescription(String description) . public String getDescription() . 清单 3 展示了一个静态的工厂方法构造。在这个例子中,class属性指定了包含静态工厂方法的类的名称。这个静态工厂方法的名称由factory-method属性指定。Blueprint Container 将对AccountFactory类调用createAccount()静态方法并将2作为参数传递,用于创建Account对象。当工厂返回创建的对象后,容器将向它注入描述属性。清单 3. 静态工厂方法示例 public class StaticAccountFactory public static Account createAccount(long number) return new Account(number); 对于实例工厂方法构建,如清单 4 所示,使用了两个管理器。其中一个管理器是工厂,另一个管理器使用该工厂创建对象。factory-ref用来指定顶级 bean 的 ID 或行为类似工厂的引用管理器。提供的工厂对象必须具有一个由factory-method属性指定的工厂方法。在本例中,accountFactorybean 管理器是一个工厂。Blueprint Container 将首先创建AccountFactory实例,该实例具有自己的参数和属性。在本例中,只指定了一个参数:工厂名。Blueprint Container 随后将对AccountFactory实例调用createAccount()方法,然后将3作为参数传递,以创建Account对象。一旦工厂返回创建的对象,容器将向其注入描述属性。清单 4. 实例工厂方法示例 public class AccountFactory public AccountFactory(String factoryName) . public Account createAccount(long number) return new Account(number); 范围根据范围设置,一个 bean 管理器可以创建一个或多个对象实例。Blueprint Container 规范指定了两个主要的范围:singletonbean 管理器创建了 bean 的单个实例,并在每次要求管理器提供对象时返回该实例。prototypebean 管理器在每次要求管理器提供对象时都将创建一个 bean 的新实例。默认情况下,singleton范围被应用于顶级 bean 管理器。scope属性不能在内联 bean 管理器中设置,因此内联管理器总是被认为具有prototype范围。scope属性用于指定范围设置。清单 5 展示了两个具有不同范围设置的 bean 定义。清单 5. 范围示例 生命周期回调bean 管理器还可以管理它所创建的对象的生命周期,并在所有属性被注入或对象被销毁时通知对象。Blueprint Container 规范指定了两种回调方法:init-method指定了一种方法,该方法在所有属性被注入时将得到调用。destroy-method指定了一种方法,该方法在 Blueprint Container 销毁对象实例时得到调用。destroy-method回调在prototype范围中不受 bean 支持。由应用程序负责销毁这些实例。所有生命周期方法都必须是公共的,不包含任何参数,并且不返回值。清单 6 展示了一个 Java 类的实例,它具有生命周期方法和一个 Blueprint XMLbean条目,后者指定了init-method和destroy-method属性。清单 6. 生命周期回调示例 public class Account public Account(long number) . public void init() . public void destroy() . 回页首服务引用管理器服务引用管理器提供了对 OSGi 服务注册表中已注册服务的访问。Blueprint 规范定义了两种服务引用管理器:引用(reference)和引用列表(reference list)管理器。引用管理器引用管理器提供了一个对象,该对象充当在服务注册表中注册了的实际服务的代理。代理允许被注入的对象保持不变,同时后端服务可以变化或被其他服务取代。对不具备后端服务的代理的调用将被阻塞,直到服务变得可用或发生超时。引用管理器由reference元素定义。代理用于等待后端服务变为可用的时间的长度将由timeout属性指定。如果timeout属性没有被指定,那么默认的超时值为 5 分钟。也可以为 Blueprint XML 文件中的所有引用管理器修改默认超时,只需要修改blueprint元素的default-timeout属性。所有超时值都以毫秒为单位指定;值为 0 则表示无限期超时。清单 7 展示了一个简单的引用管理器示例。服务代理将拥有一个 30 秒的超时。清单 7. 引用管理器示例 引用列表管理器引用列表管理器提供了一个List对象,其中包含服务代理对象或ServiceReference对象,具体取决于成员类型设置。提供的List对象是动态的,因为随着匹配服务被添加到服务注册表或从中移除,该对象可以增加或缩小。List对象是只读的并且只支持一部分ListAPI。引用列表管理器中的代理不同于引用管理器中的代理。它们使用固定的后端服务,不存在超时,并且如果后端服务变得不可用,将立即抛出ServiceUnavailableException。引用列表管理器由reference-list元素定义。提供的List对象的成员类型由member-type属性指定。member-type属性支持两种值:service-object注入一个服务代理对象列表,被认为是默认值。service-reference注入一个ServiceReference对象列表。清单 8 展示了一个简单的引用列表管理器示例。List成员为服务代理。清单 8. 引用列表管理器示例 服务选择和代理引用和引用列表管理器具有一些相同的属性。三个相同的属性用于服务选择:interface、component-name和filter。可以使用interface属性指定一个接口类。这个接口类用于两个目的:用于服务选择和服务代理。interface属性是可选的,但是如果设置了该属性,那么它必须指定一个接口类。对于服务选择,接口类被用于从服务注册表(使用该接口名注册)中选择服务。对于服务代理,服务引用管理器返回的代理必须实现由接口类定义的所有方法。如果接口属性未被指定,那么代理的行为就类似于实现一个不包含任何方法的接口。还可以将component-name和filter属性用于服务选择。component-name是一种将pname=表达式添加到选择过滤器的方便方法。类似地,filter属性指定将被添加到选择过滤器的原始 OSGi 过滤器表达式。interface、component-name和filter属性被结合在一起,创建一个用于服务选择的主要的 OSGi 过滤器表达式。例如,清单 7 中的引用的选择过滤器为(&(objectClass=java.io.Serializable),而清单 9 中的引用的选择过滤器为(&(objectClass=java.io.Serializable)(pname=myAccount)(mode=shared)。清单 9. 服务选择示例 可用性在 Blueprint Container 继续进行初始化之前,服务引用管理器需要至少一个服务匹配其选择条件。这一要求是由availability属性控制的。availability属性可以有两个值:optional匹配选择条件的服务可能存在,也可能不存在。mandatory至少存在一个匹配选择条件的服务。默认情况下,假定使用mandatory可用性。通过使用blueprint元素的default-availability属性,可以为 Blueprint XML 中的所有服务引用管理器修改默认可用性设置。具有mandatory可用性的服务引用管理器(具有一个匹配服务)被认为是可以满足需求的。具有optional可用性的服务引用管理器总是被认为可以满足需求,即使它不具备任何匹配的服务。Blueprint Container 初始化将被延迟,除非所有强制服务引用管理器都得到满足。必须要注意的一点是,只有在 Blueprint Container 初始化期间才考虑mandatory可用性。完成初始化后,随着服务在任意时刻的变化,强制服务引用将不能被满足。清单 10 展示了一个具有mandatory可用性的引用管理器的示例。清单 10. 可用性示例 引用侦听器所有服务引用管理器都可以具有 0 个或多个引用侦听器。引用侦听器指这样一些对象:当服务引用管理器选择了服务或当服务引用管理器不再使用服务时,调用回调方法。引用侦听器使用reference-listener元素指定。bind-method和unbind-method属性指定回调方法。提供回调方法的对象可以内联到reference-listener元素内,或指定为对顶级管理器的引用。绑定回调或非绑定回调都可以拥有以下任意签名(anyMethod表示一个任意的方法名)。void anyMethod(ServiceReference)该参数为被绑定或解除绑定的服务的ServiceReference对象。void anyMethod(? super T)该参数是被绑定或解除绑定的服务对象代理。服务对象必须能够指定类型 T。void anyMethod(? super T, Map)第一个参数为被绑定或解除绑定的服务对象代理。该服务对象必须能够指定类型 T。第二个参数提供与服务关联的服务属性。如果引用侦听器对一个回调具有多个超载方法,那么将调用具有匹配签名的所有方法。对于引用列表管理器,每当一个匹配服务被添加到服务注册表或从其中删除时,侦听器回调将得到调用。然而,对于引用管理器,当管理器已经被绑定到服务并且具有更低级别的匹配服务被添加到服务注册表时,绑定回调将不会被调用。类似地,当绑定到管理器的服务消失并且可以立即被另一个匹配服务取代,非绑定回调将不会被调用。必须注意,当使用引用管理器并与有状态服务交互时,应当使用引用侦听器来跟踪代理的后端服务,从而恰当地管理服务的状态。清单 11 展示了一个简单的注册侦听器示例。ReferenceListener类有两个绑定回调方法和一个非绑定回调方法,它们将作为来自服务引用列表管理器的绑定或非绑定服务被调用。清单 11. 引用侦听器示例 public class ReferenceListener public void bind(ServiceReference reference) . public void bind(Serializable service) . public void unbind(ServiceReference reference) . 回页首服务管理器服务管理器在 OSGi 服务注册表中注册服务。如果某个服务对所有强制服务引用管理器的依赖关系得到满足,服务管理器将注册或解除注册这个服务。如果强制服务引用在某一刻不能被满足,那么服务管理器将返回一个ServiceRegistration代理对象,后者将调用委托给实际的ServiceRegistration对象。在初始化期间,Blueprint Container 需要为其中的每个服务管理器注册基于ServiceFactory的服务,而不是实际的服务对象。这些服务允许 Blueprint Container 延迟对象插件,因为它们将拦截服务请求并只在需要时实例化实际的服务对象。实际的服务对象由另一个管理器提供,通常为一个 bean 管理器。实际的服务对象可以实现 OSGiServiceFactory接口。在 Blueprint XML 中,service元素定义一个服务管理器。提供服务对象的管理器可以通过ref属性引用,或内联到service元素内。清单 12 展示了两个服务:一个具有引用管理器,另一个具有内联管理器。清单 12. 服务管理器示例 服务接口每个服务都必须注册到一个或多个接口名下。服务的接口名列表可以显式指定,或由服务对象根据自动导出设置自动确定。接口名可以使用以下任一方法显式地设置: interface属性,只能指定一个单一的接口名。 interfaces子元素,允许设置任意数量的接口。自动导出设置由auto-export属性指定,并且支持以下 4 种选项。disabled如果auto-export属性未被指定,则该选项为默认值。接口列表必须使用interface属性或interfaces子元素指定。interfaces使用由服务类或其任何超类实现的所有公共接口注册服务。class-hierarchy使用服务类或其任何公共超类注册服务。all-classes结合interfaces和class-hierarchy选项。清单 13 展示了使用三种方式指定服务接口的服务。在本例中,serviceOne和serviceTwo服务使用一个Serializable接口类注册,而serviceThree服务使用MyAccount、Account和Serializable类注册。清单 13. 服务接口示例 public class MyAccount extends Account implements java.io.Serializable . java.io.Serializable 服务属性服务也可以由一组属性注册,这些属性可以使用service-properties子元素指定。service-properties元素包含多个entry子元素,每个子元素代表不同的属性。属性键使用key属性指定,但是属性值可以被指定为value属性或内联到元素内。服务属性值可以是不同类型,但是只支持原语、原语包装器类、集合或原语类型数组。清单 14 展示了使用两个服务属性注册的服务的示例。active服务属性有一个java.lang.Boolean类型的值。mode属性的类型为String。清单 14. 服务属性示例 true 如果为服务提供服务对象的管理器是顶级管理器,pname属性将被自动添加到服务属性中。pname属性的值为提供服务实例的顶级管理器的 ID。例如,对于清单 14 中的服务例子,pname属性的值将被设置为myAccount。服务级别可以使用ranking属性公开具有特定级别的服务。如果 ranking 属性未被指定,那么服务在注册时就不会具有级别。在这种情况下,OSGi 框架假设服务的默认级别为0。下面给出了一个具有级别的服务注册示例。清单 15. 服务级别示例 注册侦听器服务管理器可以具有 0 个或多个注册侦听器,注册侦听器就是指在服务被注册之后或服务被解除注册之前立即调用回调方法的对象。注册侦听器使用registration-listener子元素指定。registration-method和unregistration-method属性指定回调方法。提供回调方法的对象可以内联到registration-listener元素中,或者被指定为对顶级管理器的引用。注册回调方法或非注册回调方法的签名取决于服务对象是否实现ServiceFactory接口。如果服务实现ServiceFactory接口,那么两者都必须具有一个void anyMethod(ServiceFactory, Map)签名,其中anyMethod表示一个任意的方法名。如果服务没有实现ServiceFactory接口,那么所有回调方法都必须匹配 voidanyMethod(? super T, Map)签名,其中服务对象的类型可以被指定为 T 类型。回调方法的第一个参数是服务对象的实例,第二个参数是注册属性。如果注册侦听器对一个回调具有多个超载方法,那么具有匹配签名的所有方法都将被调用。清单 16 展示了一个简单的注册侦听器示例。清单 16. 注册侦听器示例 public class RegistrationListener public void register(Account account, Map properties) . public void unregister(Account account, Map properties) . 回页首环境管理器Blueprint Container 规范还定义了许多特殊的环境管理器,它们设置 ID 并提供对环境组件的访问。它们不具有 XML 定义,并且也不能被重写,因为它们的 ID 被保护起来,不能被其他管理器使用。环境管理器提供的对象只能被注入到使用引用的其他管理器中。Blueprint Container 规范定义了 4 种环境管理器:blueprintBundle提供包的Bundle对象。blueprintBundleContext提供包的BundleContext对象。blueprintContainer为包提供BlueprintContainer对象。blueprintConverter为包提供Converter对象,提供了对 Blueprint Container 类型转换工具的访问。类型转换小节详细对此进行介绍。清单 17 展示了一个简单示例,其中由blueprintBundle环境管理器提供的Bundle对象被注入到accountManagerOnebean 中。清单 17. 环境管理器示例 public class AccountManager public void setManagerBundle(Bundle bundle) . 回页首对象值Blueprint Container 规范定义了许多 XML 元素,它们描述各种类型的对象值。这些 XML 值元素被用于管理器定义内。例如,它们可以用于 bean 管理器,以指定参数或属性值,或用于在服务管理器内指定服务属性的值。XML 值元素被转换为实际的值对象,并被注入到管理器组件中。ref元素定义了一个对顶级管理器的引用。component-id属性指定了顶级管理器的 ID。注入的值将为由引用管理器返回的对象。清单 18 展示了ref值元素的一个例子。accountOnebean 实例被注入到accountManagerTwobean 的managedAccount属性。清单 18. 引用值示例 public class AccountManager . public void setManagedAccount(Account account) . idref元素定义了顶级管理器的 ID。被注入的值为组件 id,由component-id属性指定。idref元素被用于确保在具有指定 ID 的管理器被激活之前,该管理器确实存在。value元素表示将要从元素的字符串内容中创建的对象。您可以使用可选的type属性指定一种类型,字符串内容应该被转换为这

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论