文档章节

OSGi Event Admin Service

pior
 pior
发布于 2014/09/15 08:55
字数 1327
阅读 74
收藏 0

Event Admin是OSGi中用于bundles之间通信的手段,是处理事件的一种通用机制。采用的是pub/sub架构。

发布订阅模型

发布订阅模型应满足的需求:
1. 发布者不应该拥有订阅者的信息。
2. 新的发布者或者新的订阅者的动态增加或者删除不能影响这个发布订阅系统
3. 订阅者不应该阻塞发布者。

在发布订阅模型需要一个中间人来解耦发布者和订阅者。在Event Admin Service中这个中间人就是EventAdmin。

Event Admin service使用Topic来定义分发通道,类似于JMS。发布者发送事件到Topic,订阅者从Topic中接受信息。向Topic发送事件的发布者可以是多个,从Topic接受的订阅者也可以是多个。也就是说是一种多对多的关系。

下面是示例代码:

1
2
3
4
5
6
SimpleSubscriber subscriber = new SimpleSubscriber();
Dictionary dict = new Properties();
dict.put(EventConstants.EVENT_TOPIC,
"manning/osgi/LoginEvent" );
context.registerService(EventHandler. class .getName(),
subscriber, dict);
1
2
3
4
5
6
7
8
9
10
11
public class SimpleSubscriber implements EventHandler {
public void handleEvent(Event event) {
System.out.println( "Received event on topic = " +
event.getTopic());
for (String propertyName :
event.getPropertyNames()) {
System.out.println( "\t" + propertyName + " = " +
event.getProperty(propertyName));
}
}
}

Topic

Topic一般使用类似于java的包名的命名方法,只不过使用右斜杠替换点号。

如果使用”manning/osgi/TravelAgent/*”,则会匹配四层的事件,如
“manning/osgi/TravelAgent/CarEvent”
“manning/osgi/TravelAgent/HotelEvent”
“manning/osgi/TravelAgent/FlightEvent”
但不会匹配
”manning/osgi/TravelAgent/HotelEvent/USA”
“manning/osgi/TravelAgent”
因为它们一个是五层一个是四层。

一个空的或者不存在的EVENT_TOPIC表示不接受任何事件,一个通配符”*”表示接收所有事件。

指定多个订阅者接收多种事件的方法是使用Sring[]。

1
2
3
4
5
6
7
Dictionary dict = new Properties();
dict.put(EventConstants.EVENT_TOPIC,
new String [] { "manning/osgi/TravelAgent/CarEvent" ,
"manning/osgi/TravelAgent/HotelEvent" ,
"manning/osgi/TravelAgent/FlightEvent" });
context.registerService(EventHandler. class .getName(),
subscriber, dict);

Event

Event对象包含Topic名和时间相关的属性信息。自定义事件对象必须继承Event。关于事件的常量最好放到一个Property对象中,而不是写在代码中。

OSGi框架的事件

框架变化:包括启动类路径变化,包刷新,异常,被停止等等。
bundle变化:包括安装,更新,卸载。
服务变化:服务注册,修改,删除。

这些事件可以通过bundle context进行监听。事件会按照注册的顺序进行发送。

1
2
3
4
5
public void start(BundleContext bundleContext) throws Exception {
BundleListener bundleListener = // ...
bundleContext.addBundleListener(bundleListener);
// ...
}
1
2
3
4
5
6
7
public class MyBundleListener implements BundleListener {
public void bundleChanged(BundleEvent bundleEvent) {
if (bundleEvent.getType() == BundleEvent.INSTALLED) {
// ...
}
}
}

BundleEvent 包含一个Bundle类的实例,可以通过这个类来获取bundle的任何内容。

事件处理

EventAdmin的post方法异步发送事件,是非阻塞的;而send则是同步发送事件,是阻塞的。

要注意EvenHandler的handleEvent方法要尽快返回,而且该方法有可能被阻塞。

事件的传递顺序也受发布者发布方式的影响。如果是多线程发送,则无法保证事件的顺序。

如果handleEvent抛出一个异常,该异常并不会传递到发布者,EventAdmin会处理下一个订阅者。

EventAdmin在发送事件时会将所有可用的订阅者做一份拷贝,这就避免了订阅者收到在它存在之前的事件。同时,EventAdmin也会确保订阅者仍然注册并愿意接收事件。

由于发布者和订阅者的解耦,要特别注意发生死锁的情况。

事件过滤

使用EVENT_FILTERE来进行事件过滤。

1
2
3
4
5
Dictionary payload = new Properties();
payload.put( "price" , 80 );
Event event =
new Event( "manning/osgi/TravelAgent/HotelEvent" , payload);
admin.postEvent(event);
1
2
3
4
5
6
Dictionary dict = new Properties();
dict.put(EventConstants.EVENT_TOPIC,
"manning/osgi/TravelAgent/HotelEvent" );
dict.put(EventConstants.EVENT_FILTER, "(price<100)" );
context.registerService(EventHandler. class .getName(),
travelAgentEventHandler, dict);

Event Admin的缺点

1. 事件丢失

如果Event Admin突然挂掉,事件就会丢失。解决的办法是可以通过配置让Event Admin对事件进行持久化存储。

  1. 过滤能力有限

基于LDAP的过滤机制很难实现复杂的事件过滤。解决的方法是通过插入复杂事件处理引擎来实现。
另一个问题是对于大型系统事件的关联属性可能很多,处理起来会非常复杂,而且有可能导致事件内容过大。解决的办法是直接发送
java 对象,然后再接收端进行相应的处理。
另一个缺点是服务保证订阅者接受事件的顺序。解决的方法是扩展EventAdmin。


本文转载自:

共有 人打赏支持
下一篇: R语言手册
pior
粉丝 26
博文 151
码字总数 22496
作品 0
济南
高级程序员
私信 提问
用 Eclipse 构建轻量级的 OSGi 应用程序

简介: OSGi 一直是在 Java™ 领域及诸多其他领域中构建动态模块系统的实际行业标准。本文通过一系列相关示例展示在 Eclipse 中开发 OSGi 应用程序的过程、场景、解决方案和实践。深入阅读本...

IBMdW
2012/01/29
1K
1
JBossOSGi-1.1.0 发布

JBossOSGi-1.1.0 发布了,下载地址:jboss-osgi-installer-1.1.0.jar 这是一个 OSGi Core 4.2 的框架,该版本主要是在 AS7 的集成方面上进行全面完善。 同时还包含如下改进: Concurrency op...

红薯
2012/03/09
308
0
利用 R-OSGi 实现分布式 OSGi 应用

OSGi(Open Service Gateway Initiative)是业界中最知名的 Java 模块化技术规范,其核心设计思想是面向服务的组件模型(Service-Oriented Component Model)。OSGi 发展至今已经得到了众多企...

IBMdW
2012/06/27
1K
2
JBoss OSGi 1.0.0 最终版发布

JBossOSGi-1.0.0 Final 发布了, JBoss OSGi 是 JBoss 组织实现的 OSGi 框架,其主要的目的包括如下两个方面: 为第三方的 OSGi 框架提供一个集成的平台; 基于 JBoss 微容器提供一个 OSGi 兼...

红薯
2011/07/27
784
0
使用 Felix 和 Struts2 开发 Web 应用

Open Service Gateway Initiative(OSGi) 是一个针对 Java 动态模块开发的规范。基于中间件的 OSGi 技术提供了一个面向服务,基于组件的开发环境,并提供标准化的方式来管理整个软件生命周期。...

小编辑
2010/07/13
3.2K
4

没有更多内容

加载失败,请刷新页面

加载更多

基于 DataLakeAnalytics 的数据湖实践

随着软硬件各方面条件的成熟,数据湖(Data Lake)已经越来越受到各大企业的青睐, 与传统的数仓实践不一样的是,数据湖不需要专门的“入仓”的过程,数据在哪里,我们就从哪里读取数据进行分析...

迷你芊宝宝
29分钟前
1
0
ubuntu查看防火墙状态

1.查看防火墙当前状态 sudo ufw status 2.开启防火墙 sudo ufw enable 3.关闭防火墙 sudo ufw disable 4.查看防火墙版本 sudo ufw version 5.默认允许外部访问本机 sudo ufw default all...

Frost729
30分钟前
1
0
Gradle插件使用过程记录

Android中基于Gradle进行编译打包的过程,下面记录一下如何进行Gradle插件开发的过程: 首先在项目中新建的一个名为buildSrc的module,为什么叫这个名字请看官方文档。然后将Java文件夹以及r...

JerryLin123
37分钟前
1
0
RSA 2019安全大会:企业资产管理成行业新风向标,云上安全占优势

美国时间3月4-8日,国际知名信息安全峰会RSA Conference在美国旧金山开幕,云安全及云可以为企业提供更可靠的资产管理方式成为大会热点。 此次峰会共吸引全球700多家机构参展,其中近42%为云...

阿里云云栖社区
37分钟前
2
0
重磅推出TabLayout高级窗口组件

TabLayout是在APICloud现有窗口系统基础上升级而来的高级窗口组件,符合Material Design规范,可通过简单的配置为窗口实现原生的导航栏和TabBar,它将帮助您节省30%以上的重复编码工作量,同...

API_Cloud
42分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部