1、摘要
实体概念 | 实体概念说明 |
Bundle
|
– 安装到OSGi框架中的一个Bundle组件
|
Bundle Context
|
– 在OSGi框架运行环境中,一个Bundle的运行上下文。如果一个Bundle定义了一个BundleActivator接口的实现类并在Bundle清单【Bundle-Activator】中指明了该Activator,则OSGi框架启动和停止该Bundle时会通过该BundleActivator传入该Bundle的运行上下文
|
• Bundle Activator
|
– 一个org.osgi.framework.BundleActivator接口的实现类,OSGi框架在启动和停止该Bundle时会调用该类的start和stop方法.
|
• Bundle Event
|
– 描述一个Bundle生命周期操作的事件。当一个Bundle的生命周期状态出现变更时(如Bundle启动),所有的Bundle生命周期事件会被同步发的到所有的生命周期事件监听者.
|
• Framework Event•
|
– 描述OSGi框架状态变更的事件。所有注册的OSGi框架事件监听都会接收到该事件.
|
Bundle Listener
|
– 监听所有Bundle事件(安装,启动,停止,卸载等)的BundleListener接口实现.
|
• Synchronous Bundle Listener
|
– Bundle事件监听,该监听器监听同步发生的Bundle事件.
|
• Framework Listener
|
– 监听所有OSGi框架事件的监听器,该监听器实现FrameworkListener接口.
|
• Bundle Exception
|
– 当OSGi框架操作失败是抛出的异常.
|
• System Bundle
|
– OSGi核心框架功能的实现,该实现被看作是一个特殊的Bundle,其ID永远为0.
|
• Service
|
– 注册到服务注册表中的一个Java对象。该对象实现一个或多个接口,通过这些接口以及绑定到接口的属性列表,该对象提供接口定义的服务,该对象可以通过接口名称及属性被其他Bundle发现并使用.
|
• Service Registry
|
– 服务注册表,维护所有Bundle注册的服务.
|
• Service Reference
|
– 服务的引用。该引用只用于访问所引用的服务的属性而不是真正的服务对象。实际的服务对象必须通过Bundle的Bundle上下文获取.
|
• Service Registration
|
– 当一个服务被注册后,OSGi框架返回该对象;该对象可以用于更新服务属性及注销注册的服务.
|
• Service Listener
|
– 服务监听器,用于监听所有的服务事件(如服务的注册,变更等).
|
• Service Event
|
– 服务事件,用于描述一个对象服务的注册,修改或注销.
|
• Filter
|
– 过滤器,用于根据属性进行过滤.
|
• Start Level Service
|
– 启动等级服务,该服务用于控制Bundle的启动和停止顺序.
|
名称 | 说明 |
Bundle-ActivationPolicy: lazy | 该信息指明OSGi框架在启动时如何激活该Bundle。 |
Bundle-Activator: com.acme.fw.Activator | 该头信息指明OSGi框架在启动和停止该Bundle时调用的BundleActivator接口的类实现。 |
Bundle-Category: osgi, test, nursery | 该头信息指明Bundle的分类,多种分类以逗号分隔。 |
Bundle-Classpath: /jar/http.jar,. | Bundle的内部类路径。 |
Bundle-ContactAddress: 2400 Oswego Road, Austin, TX 74563 | 该Bundle实现厂商的联系地址 |
Bundle-Copyright: OSGi (c) 2002 | 该Bundle的版权信息 |
Bundle-Description: Network Firewall | 该Bundle的简短的描述信息 |
Bundle-DocURL: http:/www.acme.com/Firewall/doc | 通过URL指明该Bundle的文档信息所在的位置 |
Bundle-UpdateLocation: http://www.acme.com/Firewall/bundle.jar | Bundle的更新地址 |
Bundle-Vendor: OSGi Alliance | Bundle的实现厂商 |
Bundle-Version: 1.1 | Bundle的版本号 |
DynamicImport-Package: com.acme.plugin.* | 该Bundle动态引用的其他Bundle发布的包,多个包以逗号分隔。 |
Export-Package: org.osgi.util.tracker;version=1.3 | 该头信息可以将Bundle内部的类包发布出去 |
Fragment-Host: org.eclipse.swt; bundle-version="[3.0.0,4.0.0)" | 如果该Bundle是Fragment类型的,则使用该头信息描述该Bundle的Host Bundle。 |
Import-Package: org.osgi.util.tracker,org.osgi.service.io;version=1.4 | 该Bundle引用的其他Bundle发布的包,多个引用以逗号分隔。 |
Require-Bundle: com.acme.chess | 该Bundle依赖的其他Bundle |
package com.example.log;
public interface ILogService {
void debug(String message);
void debug(String message, Throwable t);
void info(String message);
void info(String message, Throwable t);
void error(String message);
void error(String message, Throwable t);
}
package com.example.log.internal;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.text.DateFormat;
import java.util.Date;
import com.example.log.ILogService;
public class LogServieImpl implements ILogService {
public void debug(String message) {
log("[DEBUG]", message);
}
public void debug(String message, Throwable t) {
log("[DEBUG]", message, t);
}
public void error(String message) {
log("[ERROR]", message);
}
public void error(String message, Throwable t) {
log("[ERROR]", message, t);
}
public void info(String message) {
log("[INFO]", message);
}
public void info(String message, Throwable t) {
log("[INFO]", message, t);
}
private void log(String level, String message) {
log(level, message, null);
}
private void log(String level, String message, Throwable t) {
StringBuffer logEntry = new StringBuffer();
logEntry.append(DateFormat.getDateTimeInstance().format(new Date()));
logEntry.append(" ");
logEntry.append(level);
logEntry.append(" ");
logEntry.append(message);
logEntry.append(" ");
if (t != null) {
logEntry.append(getStackTraceAsString(t));
}
if(t==null)
System.out.println(logEntry);
else
System.err.println(logEntry);
}
private String getStackTraceAsString(Throwable t) {
String retString = null;
if (t == null) {
return retString;
}
try {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
PrintStream printStream = new PrintStream(outStream);
if (t.getStackTrace() != null) {
t.printStackTrace(printStream);
retString = outStream.toString();
printStream.close();
} else {
return t.getMessage();
}
outStream.close();
} catch (Exception e) {
}
return retString;
}
}
在定义了日志记录服务接口及实现后,我们需要将日志记录服务发布出去供其他Bundle引用。为此,我们需要定义BundleActivator接口的实现,获取BundleContext向OSGi环境中注册该日志服务。BundleActivator接口的实现类如下:
package com.example.log.internal;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import com.example.log.ILogService;
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception {
//生成日志记录服务的实例
LogServieImpl logImpl = new LogServieImpl();
//设定日志记录服务的属性
Hashtable<String, String> properties = new Hashtable<String, String>(3);
properties.put(Constants.SERVICE_VENDOR, "ACME");
properties.put(Constants.SERVICE_DESCRIPTION, "Simple log record service");
properties.put(Constants.SERVICE_PID, ILogService.class.getName());
//注册日志记录服务
context.registerService(ILogService.class.getName(),
logImpl, properties);
}
public void stop(BundleContext context) throws Exception {
}
}
在完成日志记录服务的所有类定义后,我们需要为该Bundle编写元数据清单。在该Bundle中,我们只需要向其他Bundle发布日志服务接口包即可,其他Bundle不必了解日志记录服务是如何实现的,因此,我们在Export-Package头信息中只输出:com.example.log包。该Bundle的元数据清单如下:
至此,日志记录服务Bundle已经开发完成。
对于一个事件管理服务来说,用户使用该服务必须能够定义自己的事件,定义事件的监听处理。在本示例中,事件定义我们直接使用java.util.EventObject表示,用户可以继承此类定义自己的事件。
首先,我们定义事件监听处理IEventHandler接口:
package com.example.event;
import java.util.EventObject;
public interface IEventHandler {
void handlEvent(EventObject event);
}
package com.example.event;
import java.util.EventObject;
public interface IEventManager {
void fireEvent(EventObject event);
public void registEventHandler(IEventHandler handler);
}
package com.example.event.internal;
import java.util.ArrayList;
import java.util.EventObject;
import com.example.event.IEventHandler;
import com.example.event.IEventManager;
public class EventManagerImpl implements IEventManager {
public ArrayList<IEventHandler> handlerList = new ArrayList<IEventHandler>(
7);
public void fireEvent(EventObject event) {
for (IEventHandler handler : handlerList) {
handler.handlEvent(event);
}
}
public void registEventHandler(IEventHandler handler) {
handlerList.add(handler);
}
}
package com.example.event.internal;
import java.util.Hashtable;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import com.example.event.IEventManager;
public class Activator implements BundleActivator {
public void start(BundleContext context) throws Exception {
// 生成事件管理服务实例
EventManagerImpl em = new EventManagerImpl();
// 设定事件管理服务的属性
Hashtable<String, String> properties = new Hashtable<String, String>(3);
properties.put(Constants.SERVICE_VENDOR, "ACME");
properties.put(Constants.SERVICE_DESCRIPTION,
"Simple log record service");
properties.put(Constants.SERVICE_PID, IEventManager.class.getName());
// 注册事件管理服务
context.registerService(IEventManager.class.getName(), em, properties);
}
public void stop(BundleContext context) throws Exception {
}
}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Event Plug-in
Bundle-SymbolicName: com.example.event
Bundle-Version: 1.0.0
Bundle-Activator: com.example.event.internal.Activator
Bundle-Vendor: EXAMPLE
Import-Package: org.osgi.framework;version="1.3.0"
Export-Package: com.example.event
package com.example.file.monitor;
import java.io.File;
import java.util.EventObject;
public class FileMonitorEvent extends EventObject {
private File m_file;
public FileMonitorEvent(File file) {
super(file);
m_file = file;
}
public File getFile() {
return m_file;
}
}
package com.example.file.monitor.internal;
import java.io.File;
import java.io.FilenameFilter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.example.event.IEventManager;
import com.example.file.monitor.FileMonitorEvent;
import com.example.log.ILogService;
public class FileMonitorService {
private ILogService log;
private IEventManager em;
private String dir;
private String filter;
private File monitorDir;
protected boolean doMonitor = true;
public FileMonitorService(ILogService logService, IEventManager eventManager) {
log = logService;
em = eventManager;
}
public void start() {
String m_dir = System.getProperty("file.monitor.dir");
if (m_dir != null && m_dir.length() > 0) {
dir = m_dir;
} else {
dir = "c://osgi_test";
File f = new File(dir);
if (!f.exists()) {
if (f.mkdir())
log.info("Can not create the default monitor dir [c://osgi_test]");
} else
log.info("Property [file.monitor.dir] is not assigned, use the default value [c://osgi_test]");
}
String m_filter = System.getProperty("file.monitor.filter");
if (m_filter != null && m_filter.length() > 0) {
filter = m_filter;
} else {
filter = "//d+.txt";
}
log.info("File monitor filter rule is [" + filter + "]");
final Matcher matcher = Pattern.compile(filter).matcher("");
final FilenameFilter filenameFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return matcher.reset(name).matches();
}
};
monitorDir = new File(dir);
if (!monitorDir.exists()) {
log.info("The monitor dir [" + dir + "] is not exist!");
return;
}
new Thread("FileMonitor") {
public void run() {
while (doMonitor ) {
File[] files = monitorDir.listFiles(filenameFilter);
for (File file : files) {
log.debug("File monitor service find file ["
+ file.getName() + "]");
FileMonitorEvent event = new FileMonitorEvent(file);
em.fireEvent(event);
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
//
}
}
}
}.start();
}
public void stop(){
doMonitor = false;
}
}
package com.example.file.monitor.internal;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import com.example.event.IEventManager;
import com.example.log.ILogService;
public class Activator implements BundleActivator {
private ServiceTracker logTracker;
private ServiceTracker emTracker;
private static ILogService log;
private static IEventManager em;
private FileMonitorService fms;
public void start(BundleContext context) throws Exception {
logTracker = new ServiceTracker(context, ILogService.class.getName(),
null);
logTracker.open();
log = (ILogService) logTracker.getService();
emTracker = new ServiceTracker(context, IEventManager.class.getName(),
null);
emTracker.open();
em = (IEventManager) emTracker.getService();
fms = new FileMonitorService(log, em);
fms.start();
}
public void stop(BundleContext context) throws Exception {
if (fms != null)
fms.stop();
fms = null;
if (logTracker != null)
logTracker.close();
logTracker = null;
log = null;
if (emTracker != null)
emTracker.close();
emTracker = null;
em = null;
}
public static ILogService getLogService() {
return log;
}
public static IEventManager getEventManager() {
return em;
}
}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Monitor Plug-in
Bundle-SymbolicName: com.example.file.monitor
Bundle-Version: 1.0.0
Bundle-Activator: com.example.file.monitor.internal.Activator
Bundle-Vendor: EXAMPLE
Import-Package: com.example.event,
com.example.log,
org.osgi.framework;version="1.3.0",
org.osgi.util.tracker;version="1.3.3"
Export-Package: com.example.file.monitor
package com.exammple.file.monitor.handler;
import java.util.EventObject;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.osgi.util.tracker.ServiceTracker;
import com.example.event.IEventHandler;
import com.example.event.IEventManager;
import com.example.file.monitor.FileMonitorEvent;
import com.example.log.ILogService;
public class Activator implements BundleActivator, IEventHandler {
private ServiceTracker logTracker;
private ServiceTracker emTracker;
private static ILogService log;
private static IEventManager em;
public void start(BundleContext context) throws Exception {
logTracker = new ServiceTracker(context, ILogService.class.getName(),
null);
logTracker.open();
log = (ILogService) logTracker.getService();
emTracker = new ServiceTracker(context, IEventManager.class.getName(),
null);
emTracker.open();
em = (IEventManager) emTracker.getService();
em.registEventHandler(this);
}
public void stop(BundleContext context) throws Exception {
if (logTracker != null)
logTracker.close();
logTracker = null;
log = null;
if (emTracker != null)
emTracker.close();
emTracker = null;
em = null;
}
public void handlEvent(EventObject event) {
if (event instanceof FileMonitorEvent) {
FileMonitorEvent fm = (FileMonitorEvent) event;
if (log != null)
log.info("Receive File Monitor Event, File Name is ["
+ fm.getFile().getName() + "]");
}
}
}
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Handler Plug-in
Bundle-SymbolicName: com.example.file.monitor.handler
Bundle-Version: 1.0.0
Bundle-Activator: com.exammple.file.monitor.handler.Activator
Bundle-Vendor: EXAMMPLE
Import-Package: com.example.event,
com.example.log,
org.osgi.framework;version="1.3.0",
org.osgi.util.tracker;version="1.3.3"
Require-Bundle: com.example.file.monitor
上述示例在Eclipse中的项目实现如下图所示。点击此处下载。