火龙果软件Spring与OSGi规范.docx
- 文档编号:14599033
- 上传时间:2023-06-24
- 格式:DOCX
- 页数:27
- 大小:31.09KB
火龙果软件Spring与OSGi规范.docx
《火龙果软件Spring与OSGi规范.docx》由会员分享,可在线阅读,更多相关《火龙果软件Spring与OSGi规范.docx(27页珍藏版)》请在冰点文库上搜索。
火龙果软件Spring与OSGi规范
SpringOSGi规范(v0.7)中文版
1.0 简介
Spring框架是一个领先的full-stackJava/JEE应用框架。
它提供一个轻量级的容器,依赖注入、aop、可插接的服务抽取,这些使得非侵入式的编程模型成为可能。
OSGi提供了一个动态应用程序的执行环境,在这个环境中组件(bundles)可以在运行中被安装、更新、删除。
它同时也可以很好地支持模块化及版本化。
Spring’OSGi的目标是使得写基于Spring的应用程序尽可能的容易,这些应用可以部署到OSGi的执行环境中,并可有效利用OSGi框架所提供的服务。
通过在易用、强大的Spring框架上构建应用程序,Spring对OSGi的支持也使得开发这样的基于OSGi的应用更加简单、更加高效。
∙更好的分离应用逻辑与模块;
∙同时部署一个模块的多个版本的能力;
∙动态查找、使用系统其它模块提供的服务的能力;
∙在运行时系统中动态部署、升级、卸载模块的能力;
∙使用Spring框架在模块之间实例化、配置,集成,装饰组件;
∙让企业应用开发者使用简单、熟悉的编程模型开发OSGi平台的功能。
我们相信OSGi与Spring的结合为构建企业应用提供了最全面的可用的模型。
Spring’sOSGi的目标并不是提供一个通用的模型以支持任意的基于OSGi的应用程序开发,但是某些OSGi的开发者肯定能够发现Spring模型吸引人之处,并采纳它。
目前已经存在的OSGi的bundles以及它们所export的任何服务都可以轻松的集成到使用SpringOSGi支撑的应用中,就象是Spring已经存在的配置项。
SpringOSGi定位于OSGiR4及以上版本,JDK1.3及以上版本。
这个规范假设读者已经具有一定的Spring及OSGi的知识。
参见介绍白皮书“OSGiforSpringdevelopers”以及“SpringforOSGidevelopers”。
注意:
这些白皮书现在还不存在,还处于书写阶段,吼吼吼。
2.0BundlesandApplicationContexts
OSGi中的开发单元(以及模块单元)是bundle。
OSGi中所说的bundle有三种稳定状态:
installed,resolved,active。
Bundles可以导出(export)服务,其它的bundles可以查找并使用这个服务。
在Spring中主要的模块化单元是一个applicationcontext,它包含很多个beans(由Spring应用环境所管理的对象)。
Applicationcontexts可以分级配置,这样一个子applicationcontext可以看到定义在其上级的beans,但是反之则不行。
Spring的exporters及factorybeans的概念用于导出引用给applicationcontext外部的客户端的beans,以及注入引用到定义在一个applicationcontext外部的服务。
OSGi的bundle与Spring的applicationcontext有着本质的联系:
一个激活的bundle可以包含一个Spring的applicationcontext,负责在bundle中实例化、配置、组装以及装饰对象(beans)。
其中一些beans可以被导出(export)为OSGi服务以供其它bundles使用,在bundle中的beans也可以被轻松的注入OSGi服务引用。
2.1 在Bundle中创建ApplicationContext
一个Applicationcontext可以使用一个或多个定义了beans的XML配置文件来配置。
(严格地说,一个applicationcontext对于配置的形式并不可知,但是XML是最常用的形式)。
包含配置信息的XML文档放置于bundle中的META-INF/spring文件夹。
缺省情况下,Spring将使用在这个文件夹中的所有以“.xml”为扩展名的文档,作为applicationcontext的配置定义。
缺省设置可以在Spring-Context的manifestheader中重写。
Header的值是由逗号分隔的资源路径及指令列表。
Spring-Context:
:
=context(’,’context)*
>context:
:
=path(’;’path)*(’;’directive)*
每一个路径都被当作在bundle中定义的资源路径处理,例如:
Spring-Context:
config/application-context.xml,config/security.xml
当带有Spring-Contextmanifest入口文件或者位于META-INF/spring文件夹中的资源的bundle被激活时,Spring将自动创建applicationcontext。
为了达到这一点,你必须首先安装(install)并启动(start)在你的OSGi运行时中的org.springframework.osgi.extenderbundle。
当一个applicationcontext被首先创建后,它就判断所配置的OSGi服务引用,看是否有任何服务引用指定了cardinality(例如指定1..1或者1..n)。
直到所有必须的服务都可用之后,这个context的初始化才结束。
wait-for-dependencies指令可以在Spring-Conext头中设置为false从而改变这种行为。
当wait-for-dependencies设置为false时,如果applicationcontext在被激活时其所必须的服务还不可用,创建applicationcontext将失败。
清单头条目(Themanifestheaderentry):
Spring-Context:
*;wait-for-dependencies:
=false
表示所有在META-INF/spring中的xml文件都应该被配置,并且如果context所必须的服务不是立即可用,context的创建将会失败。
Aheaderentry:
Spring-Context:
config/application-context.xml;wait-for-dependencies:
=false
表示使用config/application-context.xml配置文件来配置applicationcontext,并且如果其所必须的服务没有立即可用,context的创建将会失败。
Applicationcontext作为org.springframework.context.ApplicationContext的一个实例被自动发布为一个OSGi服务。
此外,org.springframework.context.service.name用于设置驻留了applicationcontext的bundle的标识名称。
通过在Spring-Contextmanifestentry中指定“publish-context:
=false”可以禁止发布context为一个服务。
注意:
applicationcontext被发布为一个服务使得测试和管理变得容易。
获取一个指向在其它applicationcontext中定义的bean的首选方式是使用 reference> 和 service>元素(相对于在applicationcontext服务中调用getBean()方法)。 原因就在于通过使用 reference> 和 service>组成服务,OSGi的基础架构将保证一个bean只能看到类的版本与之相兼容的服务,反之如果在注册表中查找一个applicationcontext,然后调用getBean(…)返回一个对象,然后类兼容性的唯一保证就是ApplicationContext类自身是兼容的。 很明显在一个存在同时部署了多个版本的bundle的系统中,这种保证是不够健壮的。 2.2Spring资源抽取 Spring在applicationcontext中使用SpringResourceLoader加载资源。 相关资源路径由applicationcontext以一种与applicationcontext类型相符的方式(例如基于context的classpath,或基于context的web-app)解释。 对OSGi应用来说,相关资源路径作为从bundleclasspath中加载的资源解释。 如果资源路径以“bundle: ”前缀开头,那么只以给定的资源搜索bundle自己及其附加的fragments。 2.3BundleContextAware Spring鼓励基于不依赖于任何环境的简单对象开发应用。 但是,如果一个Springbean由于某种原因的确需要访问它的BundleContext,那么这个bean可以实现org.springframework.osgi.context.BundleContextAware接口。 实现这个接口的Bean当在applicationcontext中实例化时将会被注入BundleContext。 2.4 使用ContextClassLoader 目前存在很多很有用的第三方包及应用,它们对OSGi一无所知,并且依靠线程环境ClassLoader动态加载类。 OSGi没有定义context类加载器在任何时间点将是什么(OSGidoesnotdefinewhatthecontextClassLoaderwillbeatanypointintime.)。 这个现实与OSGi的非分级的类加载机制相符,意味着这些包将不能找到它们所需要的类和资源。 举一个简单的例子,一个应用被打包到bundleA中,使用bundleH所导出的Hibernate的类创建了一个HibernateSessionFactory。 这个SessionFactory将会需要加载定义在bundleA中的应用的类及资源,但是对于它来说,在OSGi环境中,bundleA是不可见的。 为解决这个问题,ContextClassLoader对于任何从bundleA发起调用到bundleH的线程来说必须被设置为A的bundleClassLoader。 Spring-OSGi保证了当激活一个bundle时,contextClassLoader总是被设置为能够访问被激活的bundle的资源。 这样在bean实例化及配置阶段发起的对包的调用总是产生于一个合适的contextClassLoader的上下文环境中。 请求Spring管理contextClassLoader调用OSGi服务也是可能的,以及对作为OSGi服务而暴露的beans的调用。 想了解更多的细节请参考第三部分。 2.4.1 Othercontexualaccess Springbean能够实现BundleContextAware接口以方便被注入它所在的bundle的BundleContext引用。 在bundle被激活以及其它调用某个被当作Springbean访问的OSGi服务时,Spring也会通过一个ThreadLocal变量来提供对“当前”bundle的BundleContext的访问,这个变量可通过LocalBundleContext.getContext获取。 2.5Web应用支持 Spring使用ServletContextListener,org.springframework.web.context.ContextLoaderListener来自动的为web应用创建WebApplicationContext。 OSGi可用的WebApplicationContext,org.springframework.osgi.context.support.WebApplicationContext版本提供用来在OSGi中运行web应用。 要使用这种支持,需要在你的web.xml文件中设置监听器声明的contextClass参数为“org.springframework.osgi.context.support.WebApplicationContext”。 3.0OSGi平台服务和动态本质 OSGi是一个动态的平台: bundles可能在框架运行期的任意时刻被安装、启动、更新、停止以及卸载。 在本章我们将从applicationcontext及其发布和访问的服务的角度来揭示这意味着什么。 当一个激活的bundle停止时,在它的生命周期中它所导出的任何服务也将被自动反注册,并且bundle返回到resolved状态。 停止的bundle会释放所有它所获取的资源,终止所有的线程。 停止的bundle所导出的Packages仍然对其它bundles可用。 处于resolved状态的bundle可以被卸载: 被卸载的bundle所导出的packages也仍然对其它导入它们的bundles可用(除了新安装的bundles)。 处于resolved状态的bundle也可以被更新。 更新使得bundle从一个版本迁移到另一个版本。 最后,处于resolved状态的bundle可以被启动,使它的状态转移到active状态。 OSGiPackageAdminrefreshPackages操作刷新所有OSGi框架的包或者是已安装的bundles的给定的子集。 在刷新期间,受其影响的bundle中的applicationcontext将会被停止并重新启动。 refreshPackages操作完成后,被更新的bundle的原有版本导出的包不再可用。 完整的细节内容请参考OSGi规范。 3.1 启动停止定义了applicationcontext的bundle 当包含Spring资源的bundle被激活时,这个bundle的applicationcontext会自动创建(参见2.1节)。 随后,当这个bundle被停止时,applicationcontext会被关闭然后销毁。 在context中任何实现了DisposableBean接口的单例bean或在配置中指定了destroy-method的bean将会收到通知。 当applicationcontext停止后,所有被bundle导出的OSGi服务会被反注册。 3.2OSGi服务 OSGi服务是一个在OSGi服务注册表中发布的对象,提供公开的接口。 服务也可以发布成为一组可查询的属性。 OSGi服务本质上是动态的因此使用服务的应用需要有这方面的处理机制。 OSGi提供几种不同的机制来处理动态服务,包括声明性服务(DS)规范。 使用DS时,服务组件的所有依赖都满足后被激活,服务组件也可以用一些简单的属性值(简单类型,字符串值以及这些类型的数组或vectors)和引用已发布的OSGi服务进行配置。 组件自身也可能以一个由它自己所指定的接口实现作为OSGi服务注册。 服务组件类似于Springbeans,因为它们由简单Java对象返回并且可以进行依赖注入。 然而,与Spring相比,这种依赖注入是非常有限的,没有任何在Spring中的bean可以使用的更高级功能的支持,例如AOP,声明性事务,安全,管理,导出/导入其它的非OSGi服务等等。 而且如果不以完全的OSGi服务的形式导出任何注入的服务引用,也不可能将这组服务组件与某个bundle进行组装(ItisalsonotpossibletoassembletogetherasetofservicecomponentswithinabundlewithoutalsoexportinganyinjectedservicereferencesasfullOSGiservices.)。 Spring允许在一个bundle中对bean进行完全的配置与组装,而且不需要仅仅为了在相同bundle中的另外一个bean的需要就将bean导出到bundle之外。 这样在导出(exported)bean与私有(non-exported)bean之间就有了明显的区别。 DS(相当合理地)要求服务以OSGi服务组件形式打包,并使用OSGi的语法进行配置。 当使用Spring的OSGi时,对用户来说这是一个潜在的混淆,因为在DS的概念、语法与Springbeans之间存在重叠。 Spring-OSGi能够管理在Springapplicationcontext中声明的服务之间的依赖关系,并且支持与DS相同的延迟激活语义。 Spring也完全支持动态的发布、访问服务。 Spring-OSGi使得bundles能够与使用DS的bundles和谐共存,但是对于新的bundle的开发来说,我们推荐使用SpringOSGi来代替DS。 Spring目的是提供一种简单、一致的编程模型,无论是在OSGi环境之内还是之外。 这方便了在OSGi之外的测试工作,使得不熟悉OSGi的复杂编程模型的企业Java应用的开发者更容易、更高效地进行测试。 同时,如果一些高级功能的确需要直接与OSGi协同工作,这也是支持的。 3.3 使用OSGi服务 reference>元素用于定义一个本地的bean代理某一个(或一组)OSGi服务。 唯一需要的属性是id(定义本地bean的名字)和interface(定义目标服务所注册的接口的全质类名)。 例如,定义一个本地bean代表MessageService服务: referenceid="messageService" interface="com.xyz.messaging.MessageService"/> filter属性能用来指定一个可选的OSGi框架过滤器表达式来限定一组目标服务。 可选属性depends-on保证了所声明的依赖在引用bean之前被实例化。 可选的cardinality属性允许指定引用集(cardinality)(0..1,1..1,0..n,1..n)。 缺省是“1..1”。 当指定cardinality为0..1或者1..1时, reference>元素将interface元素所指定的接口类解析为一个bean。 当指定cardinality为 0..n或者1..n时, reference>元素将interface元素解析为一个接口类元素的集合。 请看下面的配置片段: referenceid="messageService"interface="MessageService"/> referenceid="listeners"interface="MyEventListener" cardinality="0..n"/> 类“SomeClass”定义如下: publicclassSomeClass{ privateMessageServicemsgService; privateCollection publicvoidsetMessageService(MessageServiceaService){ this.msgService=aService; } publicvoidsetEventListeners(Collection this.listeners=listeners; } //... } 注意: 也可以使用原生类型Collection替代集合 3.3.1 绑定/反绑定服务资源 Spring给你一个常量对象引用,由 reference>定义(可以是一个指定为0..1或1..1的指向目标服务的代理,也可以是一个指定为0..n或1..n的Spring所管理的集合)。 这个引用背后的服务可以动态的来去。 对于持有一个集合的服务引用来说,调用iterator()操作会返回一个Iterator实例,可以遍历某个常量引用集(在调用iterator()时匹配的引用)。 集合成员可以在任何时间发生改变,因此再次遍历集合会看到不同的成员。 在任何时刻调用某个服务引用的操作都可能会失败,抛出一个unchecked(译者注: 这里应该是指不用捕获的运行时异常的意思)异常。 通过指定 reference>的timeout属性,Spring可以配置为等待指定毫秒数,以使某个服务在失败之前变成可用。 如果所要求的服务不可用,默认的行为不是立即失败(例如没有延时期)。 例如: referenceid="messageService"interface="MessageService" timeout="3000"/> 对于可选的服务引用(那些带有cardinality为0..1或0..n的服务引用),属性oneway可以设置为“true”。 如果目标服务不可用,那么通过cardinality0..1的服务引用发起的、且返回类型声明为空的操作的调用将不会抛出ServiceUnavailableException异常。 同样,如果这些操作声明返回类型为空并且目标服务在操作调用之前不可用,对通过遍历 reference>bean cardinality0..n集合而获取到的某个服务引用的操作也不会抛出ServiceUnavailableException异常。 对于无状态的服务,支持到这种级别应该足够了。 操作调用之中或之间,目标服务可能会被透明的更新。 如果当调用应用时目标服务不可用,服务可以被重试,如果还不可用,唯一的可能就是抛出ServiceUnavailableException异常。 对于有状态的服务,或者对于仅仅想加入到服务跟踪链的客户端,通过使用嵌套listener元素指明一个或多个监听器,是有可能清晰的跟踪到OSGi服务支持的服务引用(OSGiservicesbackingaservicereference)的可用性的。 referenceid="messageService"interface="MessageService"> listenerref="aListenerBean"/> listenerref="anotherListenerBean" bind-method="serviceAvailable" unbind-method="serviceUnavailable"/> reference> 如果bind-method和unbind-method属性都没有指定,那么被监听器引用的bean的类名必须实现Spring的TargetSourceLisfcycleListener接口。 如指定了bind-method或者unbind-m
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 火龙果 软件 Spring OSGi 规范