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

1

点赞

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

3

点赞

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

新建主题 记录代码

学员动态

  • 天**君回复了d**g在课程中的问题:不同的修饰代表方法的...
  • A**e在课程中提出了问题
  • 斑**斓添加了笔记:String for...
  • k**5添加了笔记:Java平台提供了很...
  • s**9向课程作业中提交了代码
  • F**e向课程作业中提交了代码
  • h**z向课程作业中提交了代码
  • t**t添加了笔记:因此,在方法执行时,...
  • w**n添加了笔记:Servlet AP...
  • c**e在课程作业中回复了老师:And, why i...
  • z**w向课程作业中提交了代码
  • S**S评论了d**7在课程中的作业:这里除了要判断tit...
  • 天**君回复了d**g在课程中的问题:代码提交上...
  • z**w向课程作业中提交了代码
  • d**g在课程中提出了问题:老师,请问代码哪里出...
  • d**g在课程作业中回复了老师:老师,我找到cons...
  • 天**君评论了d**g在课程中的作业:你的代码有编译错...
  • 咲**i在课程中提出了问题:还有就是 我用的ec...
  • t**t添加了笔记:意实际传入的类型参数...
  • L**R向课程作业中提交了代码
  • h**g向课程作业中提交了代码
  • 咲**i在课程中提出了问题:对呀 如果是在cla...
  • F**e向课程作业中提交了代码
  • v**s向课程作业中提交了代码
  • c**e在课程作业中回复了老师:understand...
  • 8**u添加了笔记:包装 Integer...
  • 天**君回复了h**g在课程中的问题:看看提示信息中那个l...
  • a**e在课程作业中回复了老师:喔,谢谢啊。帮我解锁...
  • 8**u向课程作业中提交了代码
  • l**r向课程作业中提交了代码
  • S**S评论了a**e在课程中的作业:List<Strin...
  • F**n向课程作业中提交了代码
  • t**t添加了笔记:泛型类支持多个类型参...
  • c**g向课程作业中提交了代码
  • 天**君回复了l**9在课程中的问题:欢迎来到天码营学习,...
  • F**e向课程作业中提交了代码
  • b**i添加了笔记:3.所有的标识符都应...
  • d**g在课程中提出了问题:代码已经提交,麻烦老...
  • 斑**斓向课程作业中提交了代码
  • b**0添加了笔记:Integer in...
  • c**e向课程作业中提交了代码
  • d**g在课程作业中回复了老师:好的,那除了这个还有...
  • 天**君回复了R**c在课程中的问题:欢迎来到天码营学习,...
  • t**t添加了笔记:编译器会将初始化构造...
  • 天**君评论了j**e在课程中的作业:看看编译错误提示,你...
  • t**t添加了笔记:,用static修饰...
  • 天**君评论了d**g在课程中的作业:你的截图中不是有编译...
  • l**1向课程作业中提交了代码
  • d**g在课程作业中回复了老师:那怎么设置输入呢...
  • d**7向课程作业中提交了代码
  • 8**u添加了笔记:a+=1 等于a= ...
  • b**i添加了笔记:2.注意System...
  • 天**君回复了斑**斓在课程中的问题:欢迎来到天码营学习,...
  • 天**君回复了咲**i在课程中的问题:欢迎来到天码营学习,...
  • S**S评论了d**g在课程中的作业:要在你本地的Ecli...
  • j**e在课程作业中回复了老师:怎么调用 不同数据类...
  • c**e向课程作业中提交了代码
  • S**S评论了d**g在课程中的作业:没什么问题...
  • d**7向课程作业中提交了代码
  • a**e在课程作业中回复了老师:[博客创建时间] ...
  • d**g在课程作业中回复了老师:可是运行之后显示这一...
  • t**t添加了笔记:,且每个代码块只能执...
  • j**e向课程作业中提交了代码
  • 咲**i在课程中提出了问题:老师我虽然完成了这个...
  • z**w向课程作业中提交了代码
  • z**w向课程作业中提交了代码
  • F**e添加了笔记:Java是一种大小写...
  • b**g添加了笔记:Java要求在使用一...
  • d**g在课程作业中回复了老师:先前不是您说没问题的...
  • 天**君回复了咲**i在课程中的问题:你理解和教程不太一样...
  • T**M添加了笔记:变量一般都是以小写开...
  • L**R添加了笔记:与大部分编程语言相同...
  • b**i添加了笔记:数学运算中存在自动类...
  • 一**狗添加了笔记:increase(i...
  • b**i添加了笔记:4.Java中的注释...
  • 斑**斓添加了笔记:public sta...
  • b**i添加了笔记:a++;a += 1...
  • z**w向课程作业中提交了代码
  • h**g在课程中提出了问题:这是什么情况啊,把系...
  • a**e在课程作业中回复了老师:[博客创建时间] ...
  • L**R添加了笔记:'=='和'!='作...
  • t**t添加了笔记:因此,在方法执行时,...
  • c**e在课程作业中回复了老师:what is th...
  • t**t在课程作业中回复了老师:一直显示没有加.后面...
  • 一**狗向课程作业中提交了代码
  • F**e向课程作业中提交了代码
  • d**g在课程作业中回复了老师:麻烦老师帮我看一下这...
  • 天**君评论了d**g在课程中的作业:你把代码贴到本地。注...
  • R**c向课程作业中提交了代码
  • w**w向课程作业中提交了代码
  • t**t向课程作业中提交了代码
  • t**t添加了笔记:泛型类支持多个类型参...
  • k**5添加了笔记:import jav...
  • L**R添加了笔记:Scanner sc...
  • R**c向课程作业中提交了代码
  • c**e在课程作业中回复了老师:oh thx btw...
  • 天**君回复了a**e在课程中的问题:欢迎来到天码营学习,...
  • t**t添加了笔记:有static修饰的...
  • S**S评论了a**e在课程中的作业:List<Strin...
  • R**d添加了笔记:booleanExp...
反馈意见