OSGi起步(5):使用服务

C++模块化开发实战:CppMicroServices框架解析与插件化系统构建 在C++大型项目开发中,模块化设计和动态加载是提升代码可维护性和系统可扩展性的核心诉求。传统单体架构常因模块间紧耦合导致编译缓慢、部署困难,而动态链接库虽提供了一定灵活性,却难以实现运行时真正的服务解耦与热插拔。OSGi规范为模块化提供了成熟的架构思想,其核心在于将模块(Bundle)与服务(Service)分离,通过服务注册中心实现基于接口的松耦合通信,从而赋予系统动态更新和插件化能力。CppMicroServices作为OSGi在C++领域的正统实现,将这一理念落地,通过定义Bundle元数据、服务接口 阅读详情

---------------------

原地址:http://www.eclipsezone.com/eclipse/forums/t90796.html

原作者:Neil Bartlett

---------------------

OSGi起步(5):使用服务

 

上一部分,我们知道了如何注册一个服务。这一次,我们来看看怎么去查找和使用另一个bundle注册的服务。

 

和以前一样,我们使用Martin Fowler关于“依赖注入”的论文里提到的例子。我们已经创建了一个MovieFinder,并且把它做为服务注册到注册表中。现在,我们来创建一个MovieLister,它将使用MovieFinder来查找某个导演执导的影片。我们假设MovieLister本身也是一个服务,它将被其他bundle使用,比如一个用户界面程序。这就有麻烦了,因为OSGi的服务是动态的,它们存在与否都是可能的。这意味着,有时候我们想去调用MovieFinder服务,却意外地发现它并不可用!

 

MovieFinder服务不存在的时候,MovieLister该怎么处理呢?很显然,调用MovieFinder是MovieLister很重要的一个工作,所以我们只有很少的几个可选的选项:

1、返回一个错误,比如,返回null或者抛出一个异常;

2、等待;

3、一开始就不出现。

本文中,我们将把注意力集中在前两个选项上,因为它们比较简单。一开始,你可能会觉得第三个选项没有任何意义。不过,在我们实现前两种方法以后,它会变得很让人期待。

 

我们要做的第一件事是,为MovieLister定义一个接口。复制以下代码到osgitut/movies/MovieLister.java:

 

package osgitut.movies;

import java.util.List;

public interface MovieLister {

    List listByDirector(String name);

}
 

接着,创建文件 osgitut/movies/impl/MovieListerImpl.java:

package osgitut.movies.impl;

import java.util.*;

import osgitut.movies.*;

import org.osgi.framework.*;

import org.osgi.util.tracker.ServiceTracker;

public class MovieListerImpl implements MovieLister {

    
private final ServiceTracker finderTrack;

    
public MovieListerImpl(ServiceTracker finderTrack) {

        
this.finderTrack = finderTrack;

    }


    
public List listByDirector(String name) {

        MovieFinder finder 
= (MovieFinder) finderTrack.getService();

        
if(finder == null) {

            
return null;

        }
 else {

            
return doSearch(name, finder);

        }


    }


 
    
private List doSearch(String name, MovieFinder finder) {

        Movie[] movies 
= finder.findAll();

        List result 
= new LinkedList();

        
for (int i = 0; i < movies.length; i++) {

            
if(movies[i].getDirector().indexOf(name) > -1) {

                result.add(movies[i]);

            }


        }


        
return result;

    }


}


这大概是到目前为止我们所写的最长的代码了。那么这些代码在做什么呢?首先,我们注意到,为了与OSGi相关的代码保持松散结构,查找电影的实际过程被提取到了doSearch(String ,MovieFinder)方法中。虽然,我们所用的查找方法很差而且没有效率,不过,做为一个教程,这倒是不重要。而且,数据库中只有两部电影:)

 
listByDirector(String name)
方法很有意思,它使用ServerTracker对象从服务注册表中获取MovieFinder。ServiceTracker是一个很有用的类,它掩盖了OSGi API底层许多乏味的细节。但是,我们仍然需要检查一个服务是否确实存在。我们假设ServiceTracker将在构造函数中传入。

在bundler的控制器(activator)中创建ServiceTracker是一个不错的主意。复制以下代码到osgitut/movies/impl/MovieListerActivator.java :

package osgitut.movies.impl;

import java.util.*;

import org.osgi.framework.*;

import org.osgi.util.tracker.ServiceTracker;

import osgitut.movies.*;

public class MovieListerActivator implements BundleActivator {

    
private ServiceTracker finderTracker;

    
private ServiceRegistration listerReg;

    
public void start(BundleContext context) throws Exception {

        
// Create and open the MovieFinder ServiceTracker

        finderTracker 
= new ServiceTracker(context, MovieFinder.class.getName(), null);

        finderTracker.open();

        
// Create the MovieLister and register as a service

        MovieLister lister 
= new MovieListerImpl(finderTracker);

        listerReg 
= context.registerService(MovieLister.class.getName(), lister, null);

        
// Execute the sample search

        doSampleSearch(lister);

    }


    
public void stop(BundleContext context) throws Exception {

        
// Unregister the MovieLister service

        listerReg.unregister();

        
// Close the MovieFinder ServiceTracker

        finderTracker.close();

    }


    
private void doSampleSearch(MovieLister lister) {

        List movies 
= lister.listByDirector("Miyazaki");

        
if(movies == null) {

            System.err.println(
"Could not retrieve movie list");

        }
 else {

            
for (Iterator it = movies.iterator(); it.hasNext();) {

                Movie movie 
= (Movie) it.next();

                System.out.println(
"Title: " + movie.getTitle());

            }


        }


    }


}
 

现在,这个activator开始变得有趣起来了。首先,在start方法中,创建了一个ServiceTracker(服务追踪器)对象,它将被我们刚刚写的MovieLister使用。接着,这个“追踪器”被“释放”,并开始在注册表中查找MovieFinder服务。然后它创建MovieListerImpl对象,并把它以“MovieLister”注册到服务注册表中。最后,为了在启动bundle的时候发生一些有趣的事情,activator简单地搜索了一下MovieLister然后输出结果。

我们需要编译并安装这个bundle。这一次,我不再给出完整的指令。你应该能够根据之前所做的实现这个操作。记住,你还需要创建一个manifest文件,并指明它的Bundle-Activator是osgitut.movies.impl.MovieListerActivator。另外,Import-package一行应该包含三个从其它bundle导入的package,分别是:org.osgi.framework, org.osgi.uitl.tracker和osgitut.movies.

一旦你把MovieLister.jar安装到Equinox的运行环境中,你就可以启动它了。这时,你将看到两条或者三条消息,这取决于BasicMovieFinder bundle自从上一次起是否还在继续运行。如果没有,你将看到:

osgi> start 2

Could not retrieve movie list

如果在运行,将看到

osgi> start 2

Title: Spirited Away
 

停止或者启动不同的bundle,你将看到你希望的每一条消息。这差不多就是本次要讲的所有内容了,除了我刚才说的,当一个服务不可用的时候,你还可以选择等待。由现有的代码,应该是很容易实现的:把MovieListerImpl的第16行的getService()改为调用ServiceTracker的waitForService(5000),然后添加try/catch块来处理异常InterruptedException。

 
一般来说,我不建议像这样子将一个线程挂起。这种情况是很危险的,因为listByDirector()方法是由bundle的activator的start方法调用的,而它将被框架线程调用。activator通常被要求快速返回,因为当一个bundle处于活动状态的时候,将有一系列的事情发生。事实上,在最坏的情况下,还可能产生死锁,因为我们进入了到框架所拥有的一个对象的synchronized(同步)段中,而这个对象很可能已经被别的东西给阻塞了。一个比较好的建议是,永远不要再一个bundle的activator的start方法中,或者直接被框架调用的代码中,进行长时间的操作和阻塞。

 
下一次,我们将看看当依赖不存在的时候,如何实现第三种方法:“一开始就不出现”。不要走开。

 

加密视频如何破解 如何解除机器码绑定的视频 这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 如何破解加密... 阅读详情

相关推荐

UE5在Ubuntu22.04.4下的高效开发环境配置指南

本文详细介绍了在Ubuntu 22.04.4系统上配置UE5高效开发环境的完整指南,包括系统准备、显卡驱动安装、UE5引擎编译与配置、开发工具链设置以及性能优化技巧。通过逐步指导,帮助开发者快速搭建稳定的UE5开发环境,解决常见问题,提升开发效率。

weixin_29251131的博客 383

服务追踪(ServiceTracker)

介绍 ServiceTracker是基于osgi开发中用于查找已经发布的服务的。 服务追踪器是由org.osgi.util.tracker.ServiceTracker类实现,它的作用是监视服务何时被添加、何时被移除(在添加和移除服务时框架会自动调用addingService()和r...

chuannaoxuan4674的博客 841

华为C语言笔试题(附答案)

华为C语言笔试题(附答案)     1、局部变量能否和全局变量重名?   答:能,局部会屏蔽全局。要用全局变量,需要使用 ":: "   局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。  

峰云四起 3031

OSGI中ServiceTracker的应用

OSGI中ServiceTracker的应用前文讲了ServiceListener,ServiceListener用于监听各种服务,但是如果要监听某一种服务的话,可能要花费一番功夫才能完成,但是我们可以使用osgi中另外一个监听服务的方式,就是ServiceTracker,这个在本质上是对ServiceListener的一种封装,对service的获取比ServiceListener比起来又简单许多

u012734441的专栏 1万+

附录B:Standard Delay Format(SDF)(上)

本附录将介绍标准延迟标注格式,并说明了如何在仿真中执行反标。 延迟格式描述了设计网表的单元延迟和互连走线延迟,无论设计是用两种主要硬件描述语言(VHDL或Verilog HDL)中的哪一种所描述的。 本章还会介绍仿真的反标(backannotation),STA的反标其实是一个简单直接的过程,其中DUA中的时序弧将由SDF所指定的延迟进行标注。

To the beyond and infinity! 5408

手把手教你学Simulink——基于核能发电系统的场景实例:核电站汽轮机与发电机协调控制仿真

在核电机组中,汽轮机-发电机系统是将核能最终转化为电能的关键环节。与火电机组不同,核反应堆的热惯性大、功率调节慢,因此汽轮机的控制策略需与反应堆特性相匹配,实现安全、稳定、高效的能量转换。维持发电机输出功率/频率稳定(响应电网调度)调节汽轮机进汽压力(匹配一回路蒸汽供应)实现“堆-机协调控制”保障机组在启停、变负荷、甩负荷等工况下的安全性本教程将带你使用构建一个核电站汽轮机与发电机协调控制系统汽轮机调速系统(调门控制)建模发电机与电网接口建模(同步机)

MHD0815的博客 212

osgi实战学习之路:8. Service-3之ServiceTracker

通过ServiceTracker可以对查找的Service进行扩展 下面的demo引入装饰器模式对Service进行日志的扩展 demo: Provider student-manage/Activator.java package com.demo.service; import java.util.Dictionary; import java.util.Has

我本颠坤 2231

RK3568平台(平台总线篇)Gsensor STK8BA50

Gsensor,即加速度传感器(Accelerometer),是一种用于测量物体加速度的电子设备。以下是其关键点:1.工作原理MEMS技术:大多数Gsensor基于微机电系统(MEMS),通过检测质量块的位移来测量加速度。压电效应:部分Gsensor利用压电材料在受力时产生电压的特性来测量加速度。2.主要功能加速度测量:测量物体在X、Y、Z三个方向上的加速度。倾斜检测:通过重力加速度判断设备的倾斜角度。运动检测:识别设备的运动状态,如静止、移动、晃动等。震动检测:感知设备的震动或冲击。

weixin_49303682的博客 479

java 调用felix_使用eclipse开发felix的OSGI插件

1、官网下载http://felix.apache.org/downloads.cgi,当前最新版本6.0.3运行felix窗口有两种方式(1) 可以直接下载发布版本Felix Framework Distribution(org.apache.felix.main.distribution-6.0.3.zip) 解压后目录 进入项目目录,命令行下执行java -jar ./bin/felix.j...

weixin_35081861的博客 864

一次请求穿过的六道关卡:微服务基础组件的通信与IO、事件驱动、负载均衡、服务路由、API网关与配置协调

微服务的稳定性往往取决于看不见的基础组件。本文跟随一次下单请求,依次穿过API网关、服务路由、负载均衡与服务通信,再沿事件分支扇出,并从控制面审视配置中心。通信层剖析握手成本、连接复用、epoll与主从Reactor、心跳判活、退避抖动、截止时间与重试预算;事件层讲解编舞与编排、事务发件箱和幂等消费;均衡与路由对比静态与动态算法、路由链、全链路灰度与同区保底;网关讨论过滤器链与限流算法;配置部分给出四类配置、长轮询与共识协调,最后归纳五道防线。文中关键数据均来自可在Java8运行的演示程序。

曾经“等你生日那天”都遥远得像未来,如今却可欢愉的挥手说“下个十年见” 172万+

海康网口相机不能被flexscan3d识别到MVS版本为4.6.1,flex为3.3.24在MVS中能够检测到,但是在flex中只能看到电脑自带相机,如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 1040

OSGi bundle之间互相通信的方法

摘要 OSGi的一个标准就是各个bundle之间是相互隔离的,每个bundle都有自己的classloader,并且不同的版本之间都是相互隔离的,这样就使bundle从物理上进行了隔离,那么OSGi 的bundle之间是怎么进行通信的呢? 下面我们将要介绍3中方法。 Bundles之间通信的方法 方法 描述 ...

578

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Bundle.update:OSGi现状

OSGi 4.2已经发布一月有余了(查看InfoQ的报道),在这一个月当中都发生了哪些事情呢?\u0026#xD;\n今年初发布的Equinox 3.5实现了OSGi规范草案,而最近发布的Apache Felix 2.0也提供了对OSGi 4.2的支持。除此之外,前几天发布的Knopflerfish 3.0 beta除了框架加载器还在开发当中外已经实现了4.2核心。\u0026#xD;\n两周前发...

啊啊啊啊2 307

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Racket 仓库内嵌 lz4(1) 命令手册深度解读:压缩、解压、多线程与全部选项实战指南

本篇技术指南以 Racket 仓库中 ChezScheme 子系统内嵌的 lz4 项目 [programs/lz4.1.md](https://link.gitcode.com/i/79a2b7e8e9c3c3d51f1127bd6d02712b) 命令手册为核心骨架,结合同目录下的 CLI 源码、库实现与测试脚本,系统讲解 `lz4` / `unlz4` / `lz4cat` 三个命令的完整用法

gitblog_00188的博客 965

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

OSGi近况总结:用户群蓬勃发展

OSGi近况总结:用户群蓬勃发展 作者:八神   出处:51CTOJava   2009年10月23日 09:30          今年九月下旬发布了OSGi 4.2规范,至今已经一个月有余。InfoQ的Alex Blewitt总结了这一个多月来的OSGi进展情况,应该说是一片大好,十分热闹。下面请看详情: ...

软件生产流程和软件人员心理的思考-Alfred 196

大型CMS产品研发心得:参考OSGI实现插件机制

[size=medium]最近一两年一直在负责一个内容管理产品的研发,十几个人的团队,产品核心部分有40万行代码的规模,扩展功能有约10万行代码,分成50多个插件。说是大型CMS应用,实际上对于互联网应用来说依然是一个小型应用,毕竟产品基本不上不可能会运行在超过十台服务器的集群上。 首先说说我们的现状: 1、专职开发团队,有专职的设计工程师、前端工程师、JAVA工程师、测试工程师,本...

iteye_1767的博客 282

tiny11builder 指南:2 条命令把官方 Windows 11 镜像精简成可引导的 tiny11.iso

tiny11builder 是基于 PowerShell + 微软官方 DISM 的 Windows 11 镜像精简工具:输入 2 条命令,脚本自动移除 50 余个预装应用与遥测广告,产出可引导的 **tiny11.iso**,镜像体积通常缩小 **30%~50%**,全程约 20~40 分钟。 ## 一、先看成果 跑完一遍,脚本所在目录里多出 2 样东西: - **tiny11.iso**

gitblog_00919的博客 383

web进修之—Hibernate起步(1)

web进修之—Hibernate起步(1) web进修之Hibernate起步1 一简介 二准备 下载Hibernate Hibernate下载后的目录结构介绍 H2简介 其他 三第一个例子 新建工程 引入jar包 详细代码 测试 回顾分析 四总结一、简介 ORM(**O**bject/**R**elational **M**apping) 支持JPA(**J**ava **P**ersistenc

lack的专栏 696

java开发桌面eclipse_使用Eclipse RCP进行桌面程序开发(一):快速起步

#re: 使用Eclipse RCP进行桌面程序开发(一):快速起步[未登录]回复更多评论2008-11-06 18:13 by bruce我导出后不能运行啊,一直都在报错,我就是按照上面的过程做的,哪位大侠明白,请指点迷津!下面是错误代码:!SESSION 2008-11-06 18:06:42.375 -----------------------------------------...

weixin_32487557的博客 444

InfoQ中文站第45周精彩新闻回顾

InfoQ中文站第45周最佳新闻回顾,包括Spring 2.5:支持OSGi、AspectJ和完全基于注解配置,Visual Studio 2008将于本月底发布,从Workshop起步:谈Rails专业培训,WebTest比拼Selenium:模拟和真实浏览器上的测试,企业SOA到头了?及一图胜千言?等。\ Java: Spring 2.5:支持OSGi、AspectJ和完全基于注解配置 ...

cpongo5 157

国内云服务格局初定,中小玩家SaaS是突破点

立足于国内,虽然大型企业纷纷踏足云服务市场,但是在IaaS市场之外,SaaS市场却尚未有巨头介入,或是没有“生”出巨头。而PaaS由于上下两层的挤压也一直未能够得到很好的发展——这两大市场将是中小型云服务商的机会。 虽然“云服务”在20世纪90年代就已经出现,但其真正的起步还得从2006年亚马逊云服务AWS的“一炮打响”开始。当年,如同智能家居的“智能音...

weixin_33675507的博客 398

关于Eclispe插件开发起步(一)

Eclipse中三个最吸引人的地方是: 第一是它创新性的图形API,就是SWT/JFace. 第二是它的插件机制. 第三个是利用它的插件机制开发众多功能强大的插件. 插件成就了Eclipse的今天.Eclipse的内核很小,其他功能都是基于这个内核上的插件. 如Eclipse中自代的JUnit,Ant等.如果微软愿意他可以把Office软件做成Eclip...

weixin_34404393的博客 107

Weasis:颠覆性开源DICOM查看器的企业级部署与架构解析

在医疗影像诊断领域,传统商业软件的高昂成本和封闭架构已成为医疗机构数字化转型的主要障碍。Weasis作为一款基于Java开发的完全开源专业医学影像查看器,通过创新的OSGi模块化架构和完整的DICOM 3.0标准支持,为医疗机构提供了零许可费用的企业级解决方案。本文将深入剖析Weasis的技术架构、部署策略和实际应用价值,展示如何利用这一开源工具构建可扩展的医学影像分析平台。 ## 医疗影像处理

gitblog_00657的博客 357
上一篇: OSGi 起步(4): 注册服务
下一篇: OSGi起步(6):动态追踪服务
devonzzb
博客等级 码龄25年 7粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值