`

OSGi笔记(1)

阅读更多
关键字:   OSGi    

借助网上的一些资料,对OSGi有了一些了解,将到目前的一些粗浅认识记录如下,由于自己对J2EE比较熟悉,所以借助与J2EE的对比来认识OSGi。

Module

OSGi中具体实现Module的单位是bundle,一个bundle就是一个jar文件,其中包含所需的类文件和资源文件,同时必须包含一个描述文件;每个bundle都可以被独立打包、部署。看到这里,你是否会觉得跟J2EE中的WAR定义很类似?

单从形式上来看,它们的确非常相似,而且它们的区别主要在于:
1)J2EE的WAR文件的粒度很大,是以应用为单位的;而OSGi bundle的粒度则相对小很多,以一组服务为单位,一个OSGi应用将包含多个bundle。

2)最重要的差别是,bundle之间可以通过共享java package、发布或者引用服务进行协作。而Web应用之间几乎是不存在协作的,起码在定义上没有。

3)在J2EE中,可以将多个war文件打包成为一个ear文件进行部署,而OSGi/bundle则没有这种"Application"的概念,每个bundle都必须独立部署。

Life Cycle

bundle拥有自己的生命周期,可以被安装、启动、激活、停止等,这一点与J2EE中的WAR也非常相似。不过由于不存在协作关系,WAR的生命周期相对简单,只关心自己能否启动则可。而bundle在被激活之前,必须保证其依赖的其他bundle已经存在。

Class Loading

在J2EE Servlet规范中,对ClassLoader的着墨不多,不过目前各产品的实现都比较类似,就是每个WAR文件有一个独立的ClassLoader。 如下图,由于WebApp1和WebApp2使用不同的ClassLoader,因此它们可以使用同一个Java Class的不同版本:

java 代码
  1. +-----------------------------+  
  2. |         Bootstrap           |  
  3. |             |               |  
  4. |          System             |  
  5. |             |               |  
  6. |          Common             |  
  7. |         /      \            |  
  8. |     Catalina  Shared        |  
  9. |               /    \        |  
  10. |          WebApp1  WebApp2   |  
  11. +-----------------------------+  
<script type="text/javascript">render_code();</script> (from http://tomcat.apache.org/tomcat-4.1-doc/class-loader-howto.html

在这张图中我们可以看到Catalina用独立的ClassLoader,这是一个进步。早期很多人都遇到过这样的问题,自己的应用中采用了某个开 源软件,部署的时候却无法正常运行。其原因是服务器已经采用了该开源软件的较老版本,而自己的应用却依赖与新版本。新版本的Tomcat则把自己依赖的类 库放在Catalina分支,这样这些类库对所有WebApp都不可见。同时由Shared负责的类库则是所有WebApp都能够用到。

这样的ClassLoader结构对于WebApp来说已经相当不错,但是仍然有一个问题没有解决,那就是如果WebApp1需要用到 WebApp2的类怎么办?对于WebApp来说,这种需求的确相当罕见,因为应用与应用之间一般不会出现之间的类引用。但是对于一个应用中的多个模块, 相互引用则是再正常不过了。

论坛上正好有个帖子“有关于classloader的思考(或者说是困惑)”整理了这方面的需求,我则无需重复。楼主edge_hh的问题用OSGi则可以很简单解决:
1. 在模块A的配置文件说明"Export-Package: demo.a.httpservice"
2. 在模块B的配置文件说明"Import-Package: demo.a.httpservice"
3. 将所有httpservice接口需要的定义放置在模块A的demo.a.httpservice下

这样就可以了。这就是OSGi的特别之处,bundle的CloassLoader是平级的,但平级的CloassLoader之间可以共享Java Package。

Delcare Services

在edge_hh的帖子中,他没有明确提出的一个问题是,模块B是如何调用模块A的服务?

在Java WebApp中,是不存在跨WebApp的服务调用,forward和include操作都是局限在同一个WebApp中。EJB中用<ejb-ref>来描述对EJB的引用,不过这种引用方式就如人们对EJB2的批评一样,复杂、不方便使用。

实际上在服务引用这方面,大家更加熟悉的应该是Spring的方式,如下:

xml 代码
  1. <beans>  
  2.     <bean id="ModuleA" class="demo.a.httpservice.HttpService"/>  
  3.     <bean id="ModuleB" calss="demo.b.Consumer">  
  4.         <property name="httpService">  
  5.             <ref bean="ModuleA"/>  
  6.         </property>  
  7. </beans>  
<script type="text/javascript">render_code();</script>

不过在这种场合下Spring存在的问题有:
1. Spring没有"module"的概念,难以说明“一个module包含多个service”这样的情况
2. Spring的DI是静态的,一旦建立就不会更改。而在模块化的程序中,一个模块在运行时也有卸载、重新部署的时候。Spring无法处理这种情况。

让我们来看看OSGi的做法,下面的配置代码来自《OSGI 实战》的例子:

1)声明服务:

代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <component name="DBValidator">  
  3.  <implementation class="org.riawork.demo.service.user.impl.DBValidatorImpl"/>  
  4.  <service>  
  5.   <provide interface="org.riawork.demo.service.user.Validator"/>  
  6.  </service>  
  7. </component>  
<script type="text/javascript">render_code();</script>

2)引用服务:

xml 代码
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <component name="LoginServlet">  
  3.  <implementation class="org.riawork.demo.web.servlet.LoginServlet"/>  
  4.  <reference name="ValidatorService" interface="org.riawork.demo.service.user.Validator" bind="setValidator" unbind="unsetValidator" policy="dynamic" cardinality="0..1"/>  
  5.  <reference name="HttpService" interface="org.osgi.service.http.HttpService" bind="setHttpService" unbind="unsetHttpService" policy="dynamic"/>  
  6. </component>  
<script type="text/javascript">render_code();</script>

其中特别的部分是bind和unbind的设定。通过bind和unbind,服务消费者能够知道所需服务对应模块的启动和停止,从而实现了DI的动态绑定。

"OSGi technology is the dynamic module system for Java!"

在学习OSGi之前,盛名之下,总觉得OSGi是很复杂的技术;然而在初步了解OSGi后,又觉得它非常简单,或者说是如此的清晰明了。我初步认识到OSGi的主要好处是:
1)明确定义了Moduel/Service的。
“我们的应用/系统是模块化的”,这是一句常常能听到的话语,然而个模块的具体实现方式恐怕每个应用都不尽相同,这种情况非常不利于开发团队积累 可重用的模块。现在通过OSGi的严格定义,有望形成一个标准的模块市场,Eclipse的Plug-in就是一个很好的例子。即便只是在公司范围内形成 模块仓库,都将对开发效率有极大提高。当然一个相当规模的模块市场,必然是依赖于一套设计良好的Service接口的。

2)运行时的动态性。
服务具体由哪个模块提供,模块的安装、启动、停止、卸载,这些都可以在运行时指定,并且随时更改。这样的情况下,应用的动态性就取决于你的想象力了。举一个实在的例子,我们无需重新启动整个应用,就能够对应用进行打补丁、升级。

推荐读物:《OSGi 实战》Opendoc,喜欢其中清晰明了的例子。

分享到:
评论

相关推荐

    osgi学习笔记(一)

    OSGi(Open Services Gateway Initiative)学习笔记(一) 在IT领域,OSGi是一种模块化系统和Java服务平台,它提供了一种动态管理软件组件的能力。本文将深入探讨OSGi的基本概念、架构以及如何使用它来构建可扩展和...

    osgi学习笔记(二)

    在本篇“osgi学习笔记(二)”中,我们将深入探讨OSGi(Open Services Gateway Initiative)框架的核心概念、工作原理以及如何在实际项目中应用它。OSGi是一种Java模块化系统,它允许开发人员创建可独立更新和依赖...

    OSGI学习笔记.doc

    1. **生命周期管理**:这是OSGI的核心功能之一,负责bundle的动态管理。它可以安装新的bundle,启动、停止、更新或卸载已存在的bundle,使得系统可以在运行时进行更改,无需重启。 2. **服务注册**:OSGI提供了一个...

    osgi学习笔记(三)

    在本篇OSGi学习笔记中,我们将深入探讨OSGi(Open Service Gateway Initiative)这一模块化系统,特别是关于服务方面的知识。OSGi是一个Java平台上的动态模块化系统,它允许开发者创建可热部署、互相依赖的模块,...

    『原创』OSGI研究笔记1 - Equinox ServletBridge模式下调用Datasource

    标题中的“OSGI研究笔记1 - Equinox ServletBridge模式下调用Datasource”表明了这篇文章将探讨如何在OSGI(Open Service Gateway Initiative)环境下,利用Equinox的ServletBridge模块来访问和使用DataSource。OSGI...

    osgi实战读书笔记

    ### OSGi实战读书笔记知识点总结 #### 一、Bundle的类型及特点 - **RequireBundles**: 使用了`Require-Bundle`头字段的Bundle能够访问该依赖Bundle中所有的资源文件和导出的包。这意味着如果一个Bundle声明了对另...

    Linux下OSGi框架实现笔记

    ### Linux 下 OSGi 框架实现笔记 #### 一、Linux 环境配置与准备 在开始实现 Linux 下的 OSGi 框架之前,首先需要确保已经正确配置了 Linux 的开发环境。 ##### 1. Linux 开发环境配置 **定义**:Linux 是一个...

    OSGi原理与最佳实践 学习笔记 一

    OSGi(Open Service Gateway Initiative)是一个基于Java语言的服务规范,旨在提供一个开放的服务平台,它允许多种设备通过网关来提供各种服务。OSGi Alliance是一个开放标准化组织,由多家公司共同创立,目的是为...

    SpringDM笔记28-Spring And OSGi:Layers of Integration

    1. **OSGi简介**:笔记可能首先介绍了OSGi的基本概念,包括其核心特性如服务导向架构、动态模块系统和版本管理。 2. **Spring与OSGi的关系**:Spring框架如何适应OSGi环境,可能讲解了Spring的模块化设计如何与OSGi...

    OSGi入门笔记

    1. **粒度大小**:J2EE的WAR文件通常代表一个完整的应用程序,而OSGi的bundle则更细粒度,通常以服务或功能集为单位。一个OSGi应用由多个bundle组成,每个bundle负责特定的功能。 2. **协作机制**:J2EE应用之间的...

    osgi karaf笔记

    在深入探讨OSGi Karaf的知识点之前,我们先简要了解一下Karaf与OSGi的基本概念。OSGi(Open Service Gateway Initiative)是一种Java平台上的模块化系统和应用编程框架,用于构建可动态部署、管理和更新的模块化应用...

    SpringDM笔记31-Testing with OSGi and SpringDM

    1. **OSGi基础**:首先,理解OSGi的基本概念是至关重要的。OSGi提供了一个运行时环境,使得Java应用程序可以被分解为独立的模块,这些模块可以独立地安装、升级和卸载,无需停止整个应用。它通过使用服务来实现模块...

    读书笔记:OSGI 实战 整合Maven 测试代码 .zip

    读书笔记:OSGI 实战 整合Maven 测试代码

    SpringDM笔记13-OSGi服务注册与引用

    本篇笔记将探讨如何在OSGi环境中注册服务以及如何引用这些服务,同时会涉及到源码分析和工具的使用。 首先,OSGi服务是一个在OSGi容器中注册的可发现和可使用的对象。服务注册的过程通常包括以下步骤: 1. **实现...

    读书笔记:《Java应用架构设计模块化模式与OSGi》源代码.zip

    读书笔记:《Java应用架构设计模块化模式与OSGi》源代码

    OSGI-Felix:OSGI费利克斯

    凡人的OSGi 这是我在 NA 2011,EU 2012和EU 2014上的“ OSGi的凡人”演示文稿的代码。 这是使用OSGi Declarative Services从头开始构建的最小的独立RESTful服务器,旨在证明OSGi不仅适用于超人大师。 该示例演示了...

    很久之前的osgi整理

    标题中的“很久之前的osgi整理”表明这是一份关于OSGi技术的历史回顾或者早期学习笔记。OSGi(Open Service Gateway Initiative)是一个Java模块化系统,它允许开发人员将应用程序分解为独立的模块或服务,这些模块...

    osgi-swagger-connector:OSGi - Swagger 连接器

    笔记仅在主要从 Eclipse 运行的基于 Equinox 的 OSGi 环境中对其进行了测试(Felix 和 Virgo 也可以运行)。安装一旦我完成了项目的 Tycho 构建,我将提供一个包含所有必需包的 p2 更新站点。 在此之前,您必须编译...

Global site tag (gtag.js) - Google Analytics