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

新建主题 记录代码

学员动态

  • k**e向课程作业中提交了代码
  • 天**君回复了f**o在课程中的问题:欢迎来到天码营学习,...
  • k**e添加了笔记:使用final修饰方...
  • 天**君评论了2**b在课程中的作业:我建议你再看看教程,...
  • y**n在课程作业中回复了老师:这里id超出范围的话...
  • c**8在课程中提出了问题:UP.directi...
  • w**3评论了2**b在课程中的作业:精度不对,你先让 a...
  • S**S回复了喵**咪在课程中的问题:这里是个简单的事例。...
  • 喵**咪添加了笔记:所有的标识符都应该以...
  • 喵**咪在课程中提出了问题:这个括号里面的内容是...
  • k**e添加了笔记:如果一个类的方法或者...
  • v**l在课程中提出了问题:好哒 应该是到时候会...
  • k**e向课程作业中提交了代码
  • 喵**咪添加了笔记:单行注释:在注释内容...
  • 天**君回复了z**6在课程中的问题:欢迎来到天码营学习,...
  • k**e向课程作业中提交了代码
  • c**8完成了课程的作业
  • S**S回复了v**l在课程中的问题:基础课程 暂时 不用...
  • 天**君评论了y**n在课程中的作业:LocalDateT...
  • 1**7添加了笔记:接口的继承使用ext...
  • S**S回复了c**3在课程中的问题:多看几遍教程中的强制...
  • S**r添加了笔记:在一个方法中声明的变...
  • w**3评论了2**b在课程中的作业:double a =...
  • 2**b在课程作业中回复了老师:老师你好,我想请问一...
  • 2**b在课程中提出了问题:Integer in...
  • y**n向课程作业中提交了代码
  • 天**君回复了1**8在课程中的问题:欢迎来到天码营学习,...
  • S**S评论了f**o在课程中的作业:if(grid.ne...
  • S**S评论了y**n在课程中的作业:System.out...
  • S**S评论了f**o在课程中的作业:你只需要 满足 作业...
  • S**S回复了2**b在课程中的问题:new 一个 值为 ...
  • k**e向课程作业中提交了代码
  • e**1在课程作业中回复了老师:自己试了很多次没有任...
  • 天**君回复了2**b在课程中的问题:欢迎来到天码营学习,...
  • 2**b向课程作业中提交了代码
  • k**e向课程作业中提交了代码
  • f**o在课程作业中回复了老师:空格键暂停是不是要通...
  • h**i向课程作业中提交了代码
  • 蓝**社向课程作业中提交了代码
  • k**e向课程作业中提交了代码
  • 2**b在课程作业中回复了老师:老师,请问一下为什么...
  • k**e在课程中提出了问题:temp 不能这么声...
  • 1**2评论了:...
  • 2**b在课程作业中回复了老师:老师,还是报错。。您...
  • k**e添加了笔记:final变量的所有...
  • e**1在课程作业中回复了老师:我想问一下,这里不能...
  • S**S评论了e**1在课程中的作业:输出两次 一次是初始...
  • 1**9在课程作业中回复了老师:感谢老...
  • z**g添加了笔记:格式化字...
  • w**3评论了2**b在课程中的作业:Math.sqrt(...
  • t**1向课程作业中提交了代码
  • v**l在课程中提出了问题:心疼认真看《如何开始...
  • s**k向课程作业中提交了代码
  • c**8在课程中提出了问题:我点Java Web...
  • 天**君评论了1**9在课程中的作业:默认的是/blogs...
  • 2**b向课程作业中提交了代码
  • k**e添加了笔记:反射是一种动态获取信...
  • 天**君评论了y**n在课程中的作业:调用postRepo...
  • w**3回复了w**7在课程中的问题:read() : 从...
  • k**e向课程作业中提交了代码
  • s**8添加了笔记:定义成员变量时,可以...
  • y**n在课程作业中回复了老师:谢谢老师...
  • f**o向课程作业中提交了代码
  • w**7在课程中提出了问题:package co...
  • w**3评论了k**e在课程中的作业:StringBuil...
  • f**o在课程作业中回复了老师:如何开启下一节课的作...
  • w**3评论了2**b在课程中的作业:对的 就像高中数学的...
  • y**n在课程中提出了问题:请您再看一下我的显示...
  • 2**b向课程作业中提交了代码
  • 1**9在课程作业中回复了老师:。。。老师我的功能实...
  • k**e向课程作业中提交了代码
  • f**o在课程作业中回复了老师:自己运行程序测试了,...
  • 2**b向课程作业中提交了代码
  • y**_向课程作业中提交了代码
  • y**n向课程作业中提交了代码
  • 2**b向课程作业中提交了代码
  • S**S评论了y**n在课程中的作业:处理博客不存在的情...
  • k**e在课程中提出了问题:package co...
  • w**3评论了2**b在课程中的作业:double c =...
  • S**r添加了笔记:先声明对象名称,空格...
  • h**i向课程作业中提交了代码
  • z**g添加了笔记:// 第一个构造器 ...
  • v**l在课程中提出了问题:git克隆仓库总是认...
  • B**N向课程作业中提交了代码
  • S**S评论了w**7在课程中的作业:对象需要实例化 才能...
  • w**7向课程作业中提交了代码
  • 2**b向课程作业中提交了代码
  • w**7在课程作业中回复了老师:为啥使用String...
  • s**k向课程作业中提交了代码
  • S**S回复了c**8在课程中的问题:Maven是包管理工...
  • T**丶添加了笔记:在实际项目中,我们一...
  • 天**君回复了t**1在课程中的问题:欢迎来到天码营学习,...
  • z**6向课程作业中提交了代码
  • 2**b在课程作业中回复了老师:噢噢噢噢噢噢噢噢,我...
  • s**k向课程作业中提交了代码
  • y**_向课程作业中提交了代码
  • f**o在课程作业中回复了老师:都是显示多少time...
  • 天**君回复了v**l在课程中的问题:后面的项目课程会用到...
  • 2**b向课程作业中提交了代码
  • S**S回复了c**8在课程中的问题:我的QQ是54905...
反馈意见