首先配置OSGi Framework的运行环境,我的Eclipse是3.3的,运行环境需要以下的Bundle:
? org.eclipse.osgi
? org.eclipse.equinox.ds
? org.eclipse.equinox.registry
? org.eclipse.equinox.common
? org.eclipse.equinox.log
? org.eclipse.osgi.services
? org.eclipse.equinox.event
? org.eclipse.osgi.util
操作步骤:点击菜单Run->Open Run Dialog…,在左侧的列表中,找到OSGi Framework,右键单击,New,修改Name为EventDemo,并在Bundles选项卡中,选中以上列举的Bundle,然后点击Apply,点Run。
在Console中输入ss来查看我们的环境是否成功运行:
123456789101112131415 osgi> ss
Framework is launched.
id State Bundle
0 ACTIVE org.eclipse.osgi_3.3.1.R33x_v20070828
1 ACTIVE org.eclipse.equinox.common_3.3.0.v20070426
2 ACTIVE org.eclipse.equinox.log_1.0.100.v20070226
3 ACTIVE org.eclipse.equinox.ds_1.0.0.qualifier
4 ACTIVE org.eclipse.equinox.registry_3.3.1.R33x_v20070802
5 ACTIVE org.eclipse.osgi.services_3.1.200.v20070605
6 ACTIVE org.eclipse.equinox.event_1.0.100.v20070516
7 ACTIVE org.eclipse.osgi.util_3.1.200.v20070605
osgi>
OK,这样我们的Spring-OSGi的环境就启动好了,现在先关闭它。我们来建立一个Plug-in Project,命名为:EventPublisher。
首先新建一个类:com.demo.eventpublisher.Log,代码如下:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 package com.demo.eventpublisher;
import org.osgi.framework.BundleContext;
import org.osgi.service.log.LogService;
import org.osgi.util.tracker.ServiceTracker;
/**
* Utility class with static methods for logging to LogService, if available
*
* @version $Revision: 1.1 $
*/
public class Log {
static private ServiceTracker logTracker;
private Log() {
}
public static void init(BundleContext bc) {
logTracker = new ServiceTracker(bc, LogService.class.getName(), null);
logTracker.open();
}
static void dispose() {
if (logTracker != null) {
logTracker.close();
}
logTracker = null;
}
public static void log(int level, String message) {
log(level, message, null);、
}
public static void log(int level, String message, Throwable e) {
LogService logService = (LogService) logTracker.getService();
if (logService != null) {
logService.log(level, message, e);
}
}
public static void info(String message)
{
info(message, null);
}
public static void info(String message, Throwable e)
{
log(LogService.LOG_INFO, message, e);
}
}
接下来创建一个循环发布事件的线程:com.demo.eventpublisher.TimerEvent,代码如下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556 package com.demo.eventpublisher;
import java.util.Calendar;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.util.tracker.ServiceTracker;
public class TimerEvent extends Thread implements BundleActivator {
Hashtable time = new Hashtable();
ServiceTracker tracker;
public TimerEvent() {
super("TimerEvent");
}
public void start(BundleContext context) {
Log.init(context);
tracker = new ServiceTracker(context, EventAdmin.class.getName(), null);
tracker.open();
start();
}
public void stop(BundleContext context) {
interrupt();
tracker.close();
Log.dispose();
}
public void run() {
while (!Thread.interrupted())
try {
Log.info("Rasie Event");
Calendar c = Calendar.getInstance();
set(c, Calendar.MINUTE, "minutes");
set(c, Calendar.HOUR, "hours");
set(c, Calendar.DAY_OF_MONTH, "day");
set(c, Calendar.MONTH, "month");
set(c, Calendar.YEAR, "year");
EventAdmin ea = (EventAdmin) tracker.getService();
if (ea != null)
ea.sendEvent(new Event("com/demo/timer", time));
Thread.sleep(60000 - c.get(Calendar.SECOND) * 1000);
}
catch (InterruptedException e) {
// 忽略
}
}
void set(Calendar c, int field, String key) {
time.put(key, new Integer(c.get(field)));
}
}
在Plug-in ManiFest Editor中打开META-INF/MANIFEST.MF,如果安装了PDE,将会默认使用Plug-in ManiFest Editor打开。将Activator设置为com.demo.eventpublisher.TimerEvent,此时MANIFEST.MF文件中的内容如下:
1234567891011 Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: EventPublisher Plug-in
Bundle-SymbolicName: EventPublisher
Bundle-Version: 1.0.0
Bundle-Activator: com.demo.eventpublisher.TimerEvent
Import-Package: org.osgi.framework;version="1.3.0",
org.osgi.service.event;version="1.1.0",
org.osgi.service.log;version="1.3.0",
org.osgi.util.tracker;version="1.3.2"
注意:手工写MANIFEST.MF文件时,最后一行一定要有一个回车。
接下来我们再来建立一个Plug-in Project,命名为EventHander。
我们建立一个类,名为:com.demo.eventhandler.CustomEventHandler,代码如下
12345678910111213141516171819202122232425262728293031323334353637383940414243 package com.demo.eventhandler;
import java.util.Dictionary;
import java.util.Hashtable;
import org.osgi.framework.BundleContext;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventConstants;
import org.osgi.service.event.EventHandler;
import com.demo.internal.Log;
public class CustomEventHandler implements EventHandler
{
public final static String [] topics = new String[] {
// "org/osgi/service/log/LogEntry/LOG_INFO",
// "org/osgi/service/log/LogEntry/LOG_WARNING",
// "org/osgi/framework/ServiceEvent/REGISTERED",
// "org/osgi/framework/ServiceEvent/MODIFIED",
// "org/osgi/framework/ServiceEvent/UNREGISTERING",
// "org/osgi/framework/FrameworkEvent/STARTED",
// "org/osgi/service/log/LogEntry/LOG_ERROR",
"com/demo/timer"};
public void registry(BundleContext context)
{
Dictionary d = new Hashtable();
d.put(EventConstants.EVENT_TOPIC, topics );
context.registerService( EventHandler.class.getName(), this, d );
}
public void handleEvent(Event event)
{
if ("com/acme/timer".equals(event.getTopic()))
{
Log.info("Received event, EventTopic " + event.getTopic() + " " + event.getProperty("year") + "-" + event.getProperty("month") + "-" + event.getProperty("day"));
}
else
{
Log.info("Received event, EventTopic " + event.getTopic());
}
}
}
我们再建立一个Activator,名为:com.demo.eventhandler.internal.Activator,代码如下
12345678910111213141516171819202122 package com.demo.internal;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import com.demo.eventhandler.CustomEventHandler;
public class Activator implements BundleActivator
{
public void start(BundleContext context) throws Exception
{
Log.init(context);
CustomEventHandler eventhandler = new CustomEventHandler();
eventhandler.registry(context);
}
public void stop(BundleContext context) throws Exception
{
Log.dispose();
}
}
OK,我们将新建立的这两个Bundle加入到运行环境中,Run。
在Console中等待大约60秒后,输入log后可以在最后找到如下日志信息:
引用原文:
--------------------------------------------------------------------------------
>Info [1] Rasie Event initial@reference:file:../../../../../../../../Documents/workspace/EventPublisher/
>Info [7] Received event, EventTopic com/demo/timer initial@reference:file:../../../../../../../../Documents/workspace/ConsumerServiceDemo/
--------------------------------------------------------------------------------
瞧,我们已经收到打印出来的事件接收信息了 Received event, EventTopic com/demo/timer