B

0

点赞

0

回复

4452

浏览

动态的OSGi服务

OSGI服务的动态性 我们对 OSGi服务 http://tianmaying.com/tutorial/osgi bundle coupling 已经有了初步了解,接上一个 例子 http://tianmaying.com/tutorial/osgi bundle coupling ,我们再次清空/deploy文件夹,并删除/data文件夹; 只将demo3 1.0.jar复制到/deploy文件夹下; 用list命令可以看到demo3 bundle的状态是 installed 然后我们再将demo2 1.0.jar复制到/deploy文件夹下; 用list命令可以看到demo3 bundle的状态变成了 Active ,并且输出了预期的结果。 在以上例子中,我们会发现demo3 bundle是依赖了demo2 bundle,demo3 bundle必须在demo2 bundle成为 Active 的状态时,才能变成 Resolved ,进而转成 Active 的状态。 下面,我们再来做一个试验 demo2 bundle里ICalculation接口和它的实现类Calculation是在一起的。我们建立两个工程(demo2_1和demo2_2),将它们分离开来。 在demo2_1工程里,我们依然有一个com.ponder.Demo.demo2.contract的package,里面也有一个ICalculation的接口类。 在demo2_1的pom.xml里有: ...

javaosgibundleservice

3

点赞

2

回复

3397

浏览

OSGi中Bundle间的耦合:Export/Import Package与服务

创建OSGi Hello World工程 http://tianmaying.com/tutorial/osgi helloworld 里,我们提到OSGI通过不同的classloader来加载不同的bundle,达到隔离bundle的目的,我们也提到通过Import/Export Package的方式来控制bundle之间“有限地”访问对方的类。 这里我们只有一个bundle(demo1 1.0.jar),但我们在这个bundle的manifest.mf里,可以看到设置了Import Package和Export Package。 IMPORT PACKAGE/EXPORT PACKAGE 在OSGI里,bundle暴露自己的类(Export)或引用其他bundle的类(Import)的单位是package(就是每个java代码文件最上头定义的Package),也就是对于bundle来说,只能将整个package里的类暴露或引用进来,而不是对单个类作暴露或引用,所以,我们在设计时,应考虑将需暴露出去的类放在一个或几个package里,而将需隐藏起来的类放在其他的package里。 然后,我们在manifest.mf里加入诸如: Export Package:com.ponder.Demo.demo1...

javabundleosgi

1

点赞

0

回复

4673

浏览

创建OSGi Hello World工程

OSGI BUNDLE工程 在学完《 走近Java模块化系统OSGi http://tianmaying.com/tutorial/osgi kickstart 》后我们已对osgi有初步的印象,今天我们将从一个hello world来具体地接触osgi。 我们将采用maven来构建一个简单的bundle,不熟悉maven的同学请先了解一下再继续。我们还会使用servicemix来做运行时平台,至于IDE,则不限。 首先是maven项目的pom.xml,如下: ...

bundleosgijava

4

点赞

0

回复

5324

浏览

走近Java模块化系统OSGi

OSGI是什么? 刚入软件开发行业的初哥可能会觉得到处都是值得顶礼膜拜的大神,到处都是复杂到自已无法把握的代码,惊叹这些大神怎样能写出如此神奇的程序出来?! 其实真正好的软件的代码,应该是结构清晰,简单易懂的代码(别提linux内核代码,那是另类)。 说到底,软件设计就不外乎复用、内聚、藕合三个主题。 OSGI作为Java的模块化规范,也是为了更好地解决java在这三个主题的问题。 要理解OSGI,首先要知道OSGI不是一个应用层面的框架,而是设计层面的规范,所以不要用理解spring、hibernate、structs那样的框架的方式来理解OSGI,如果一定要找一个类似的东西和OSGI对比的话,我想会是OO(Object Orient面向对象)。所以,不要问“怎么将spring和OSGI集成?”这样的问题,被象你不会问“怎么将spring和OO集成?”一样。 其次,OSGI的目的是模块化,就是为了将一个大的应用分解成较小的模块,这些模块物理上就是一个个的jar包,也就是OSGI bundle。OSGI规范就是指导怎么令这些bundle能更好的有高内聚性、有松藕性,能更好地被复用。至于被神化的“动态性”、“热插拔”的特性,则是OSGI规范带来的一种可能,并不是一定会有的。这些特性是需要配合好的设计才能达到。 最后,OSGI的课程不是去教你学会一种开发语言,也不是去教你学用一套应用框架,而是教你去设计你的应用,是一种形而上的课程,需要个人去领悟。 OSGI FRAMEWORK和BUNDLE的生命周期 OSGI规范定义了一个叫OSGI framework的平台,这个平台是一个运行在JVM上的应用。它负责管理我们上节提到的bundle(也就是一个符合OSGI规范的Jar包)。 对于bundle,我们需要关注它的生命周期。 首先,bundle需要install到osgi framework上,这个install只是让framework用一个classloader来装载bundle里的类和资源。 接着就是resolve,检查bundle需要“引用”的package是否可用,这个后续再详细介绍。 然后,bundle就要start,也就是运行activator里的start方法,方法运行完毕,即进入"ACTIVE"的状态,这时bundle就算正式可用了。 BUNDLE的隔离 “模块化”的模块是一些相对独立的实体,它们是有边界的,就好象我们在OO里看到,类也是有边界的,它一般是以一个类文件作为边界,而OSGI模块的边界则是一个Jar包,也就是一个bundle。简单的说:在OSGI范畴内,模块就是一个bundle,一个bundle就是一个模块。 在传统的java应用开发中,我们很少去关注jar包的隔离性,通常只需要知道我们的应用都用到哪些jar包,在部署时,将这些jar包一起部署,就可以用jar包里的java类了。也就是说,在运行时,一堆的jar包并不需要我们去特意去分辨它们之间的关系,部署好后,该用到谁就自然能用上谁,整个应用就是一体的,jar包的依赖关系并不清晰。 而在OSGI规范下,bundle是被“有计划地”依赖着,你得显式地说明模块之间的依赖关系。OSGI是利用JVM的classloader和它的父委托模型(PDM:Parent Delegation Mode)来实现这点的。 故名思义,classloader就是加载java类的加载器,一个classloader加载的类,就只能被这个classloader及其子classloader加载的其它类访问到。也就是说,如果两个不是父子关系的classloader加载的类是互相不可见的。 而OSGI对每一个bundle都分别用一个classloader来加载里面的类,所以不同bundle之间的类,在默认情况下,是互不可见的。 如果没有额外处理,一个bundle里的类要访问另一个bundle里的类时,通常会出现ClassNotFound的异常,可以说这个异常将是OSGI初学者最常见到的异常。 BUNDLE之间的藕合 一般来说,单个的bundle并不是完整的应用,它需要和其它bundle组合在一起才能真正发挥作用。 在上面,我们提到由于每个bundle的classloader都不同,所以它们的类是互不可见的。 为了能引用别的bundle的类,osgi通过import/export package的机制来控制bundle间有限地藕合。 在bundle的设计时,我们将需要给其它bundle“访问”的类放在若干个package内,然后export这些package,就可以让其它bundle通过import package的方式“访问”到这些package里的类,而没被Export的package里的类则被“保护”起来。 注意: Export/Import package是通过bundle里的META INF/manifest.mf文件里指定的。 更松散的藕合 OSGI SERVICE 除了通过import/export package的机制实现bundle间的藕合,我们还可以通过osgi service的方式实现藕合。osgi service是osgi规范中定义的一种本地服务的机制,“本地”意味着它只是在osgi framework内有效,不可跨osgi framework调用,更不可跨JVM调用。osgi service可以认为是一种“微服务”,可以在bundle之间引用。 osgi framework有一个service registry,bundle可以把一个实现某种接口的bean实例作为osgi service注册(register)到service registry上,其它bundle就可以从service registry上发现并引用它,所以,本质上osgi service就是一个bean。 通常,我们会把接口定义在一个bundle A里,接口的实现则在另一个bundle B里,并将接口实现实例化后注册成osgi service,而第三个bundle C则引用这个osgi service。 因为bundle B和C都需要用到bundle A的接口定义,所以bundle A需export接口定义所在的package,而bundle B和C则需import这个package。这样bundle B和C之间就不需用export/import package来藕合了,实现B和C之间的解藕。 在osgi的应用中,会有大量的osgi service存在,可以说osgi service是osgi规范中最重要的机制,没有之一。 其它机制 OSGI规范还提供了Event、配置管理(ConfigAdmin)、声明式服务(Delarative Service)、Service Tracker、Blueprint等等运行时机制,方便我们构建模块化的应用系统,这些机制,以后再介绍。 ...

osgijavabundle

新建主题 记录代码

学员动态

  • K**务创建了代码片段:毕业真实的版本=+柏...
  • a**1创建了代码片段:毕业真实版本^|佐治...
  • l**d创建了代码片段:最新毕业版【九州大学...
  • l**d创建了代码片段:毕业真实版*【北海道...
  • y**n向课程作业中提交了代码
  • l**g向课程作业中提交了代码
  • v**o向课程作业中提交了代码
  • K**务创建了代码片段:毕业真实的版本=+伍...
  • l**d创建了代码片段:最新毕业版【早稻田大...
  • y**n向课程作业中提交了代码
  • K**务创建了代码片段:毕业真实的版本=+马...
  • l**d创建了代码片段:最新毕业版【东北大学...
  • K**务创建了代码片段:毕业真实的版本=+韩...
  • K**务创建了代码片段:毕业真实的版本=+汉...
  • l**d创建了代码片段:最新毕业版【神户大学...
  • y**n向课程作业中提交了代码
  • l**d创建了代码片段:真实毕业版*【千叶科...
  • a**1创建了代码片段:毕业真实版本^|杜克...
  • K**务创建了代码片段:毕业真实的版本=+韩...
  • K**务创建了代码片段:毕业真实的版本=+莱...
  • r**i创建了代码片段:毕业真实的版本*新加...
  • L**9向课程作业中提交了代码
  • l**d创建了代码片段:最新毕业版【东京医科...
  • K**务创建了代码片段:毕业真实的版本=+杜...
  • v**g向课程作业中提交了代码
  • K**务创建了代码片段:毕业真实的版本=+韩...
  • a**1创建了代码片段:毕业真实版本^|特拉...
  • l**d创建了代码片段:毕业真实版*【一桥大...
  • S**d向课程作业中提交了代码
  • a**1创建了代码片段:毕业真实版本^|卡内...
  • y**n向课程作业中提交了代码
  • l**d创建了代码片段:最新毕业版【立教大学...
  • v**o向课程作业中提交了代码
  • v**o向课程作业中提交了代码
  • a**1创建了代码片段:毕业真实版本^|田纳...
  • a**1创建了代码片段:毕业真实版本^|埃默...
  • q**m添加了笔记:this(title...
  • K**务创建了代码片段:毕业真实的版本=+韩...
  • 天**君回复了q**m在课程中的问题:欢迎来到天码营学习,...
  • l**g向课程作业中提交了代码
  • v**o向课程作业中提交了代码
  • x**1向课程作业中提交了代码
  • l**d创建了代码片段:毕业真实版*【东京工...
  • C**s向课程作业中提交了代码
  • q**m向课程作业中提交了代码
  • a**1创建了代码片段:毕业真实版本^|维克...
  • q**m在课程中提出了问题:请问这段简化是什么意...
  • K**务创建了代码片段:毕业真实的版本=+不...
  • a**1创建了代码片段:毕业真实版本^|华盛...
  • K**务创建了代码片段:毕业真实的版本=+韩...
  • L**9向课程作业中提交了代码
  • l**d创建了代码片段:最新毕业版【龙谷大学...
  • q**m添加了笔记:trim()方法对于...
  • w**3评论了y**n在课程中的作业:可以写一个for循环...
  • a**1创建了代码片段:毕业真实版本^|利哈...
  • q**m向课程作业中提交了代码
  • a**1创建了代码片段:毕业真实版本^|范德...
  • y**n向课程作业中提交了代码
  • r**i创建了代码片段:毕业真实的版本*南洋...
  • q**m添加了笔记:方法/函数: 也可以...
  • q**m添加了笔记:???一个对象的成员...
  • v**o向课程作业中提交了代码
  • l**d创建了代码片段:最新毕业版【关西学院...
  • l**d创建了代码片段:毕业真实版*【帝冢山...
  • l**g向课程作业中提交了代码
  • w**3评论了t**y在课程中的作业:这个方法这样就行了 ...
  • a**1创建了代码片段:毕业真实版本^|南卫...
  • r**i创建了代码片段:毕业真实的版本*义安...
  • 天**君回复了C**s在课程中的问题:欢迎来到天码营学习,...
  • l**d创建了代码片段:毕业真实版*【朝日大...
  • C**丶向课程作业中提交了代码
  • K**务创建了代码片段:毕业真实的版本=+韩...
  • a**1创建了代码片段:毕业真实版本^|波士...
  • w**3回复了y**n在课程中的问题:这里是把字符串数组 ...
  • K**务创建了代码片段:毕业真实的版本=+锡...
  • q**m向课程作业中提交了代码
  • l**d创建了代码片段:毕业真实版*【放送大...
  • y**n向课程作业中提交了代码
  • l**d创建了代码片段:毕业真实版*【久留米...
  • q**m在课程中提出了问题:关于scanner部...
  • l**d创建了代码片段:最新毕业版【专修大学...
  • C**丶向课程作业中提交了代码
  • y**n在课程作业中回复了老师:为什么这一行运行不成...
  • K**务创建了代码片段:毕业真实的版本=+韩...
  • K**务创建了代码片段:毕业真实的版本=+韩...
  • q**m向课程作业中提交了代码
  • q**m向课程作业中提交了代码
  • q**m添加了笔记:switch语句判断...
  • a**1创建了代码片段:毕业真实版本^|麻省...
  • y**n在课程中提出了问题:老师好!'=='和'...
  • a**1创建了代码片段:毕业真实版本^|乔治...
  • K**务创建了代码片段:毕业真实的版本=+柏...
  • a**1创建了代码片段:毕业真实版本^|伍斯...
  • l**d创建了代码片段:最新毕业版【宇都宫大...
  • C**丶向课程作业中提交了代码
  • q**m向课程作业中提交了代码
  • a**1创建了代码片段:毕业真实版本^|加州...
  • t**y在课程作业中回复了老师:想问下我这个思路或代...
  • l**d创建了代码片段:真实毕业版*【小樽商...
  • q**m向课程作业中提交了代码
反馈意见