SAT插件引用服务、发布osgi服务

OSGi的服务层(Service Layer)为bundle之间的解耦合及服务引用提供的强大而又灵活的实现机制。通过BundleActivator控制组件的生命周期,通过BundleContext与其他组件和服务交互。但是,OSGi服务层在提供强大的功能的同时,也给使用者造成了很大的困惑,比如,组件的启动顺序,服务的查找策略等等。OSGi通过Declarative Service给出了一种通过XML配置文件发布和绑定服务的功能,用户只需要定义XML文件即可向OSGi环境中发布服务对象和获取其他bundle组件发布的服务。

在OSGi编程过程中,获取其他Bundle提供的服务是比较复杂的,尤其是获取多个服务时需要做很多重复性的工作。有没有更为简单的方式实现服务的发布和绑定呢?最近在Equinox邮件列表中看到Patrick的向equinox开发组的一项提议,建议将Service Activator Toolkit(SAT)组件添加到Equinox项目中,SAT目前位于Eclipse 技术项目OHF中。

SAT大大简化了OSGi Service Bundle开发的复杂性。用户可以通过SAT插件引用服务,发布服务,自定义Bundle Activator。下面是SAT插件的功能略图:SAT插件引用服务、发布osgi服务

上图展示了如何引用和发布服务

SAT插件引用服务、发布osgi服务

上图展示了如何定制BundleActivator。

下面通过几行简单的代码展示SAT如何简化服务的发布和引用。

//服务的发布

public class Activator extends BaseBundleActivator {

protected void activate() {

LogUtility.logInfo("The Hotdog Vendor bundle has been activated"); //$NON-NLS-1$

addExportedVendorService();

}

//将HotdogVendor服务发布到OSGi环境中

private void addExportedVendorService() {

VendorService service = new HotdogVendor();

Dictionary properties = new Hashtable(11);

properties.put(VendorService.SPICINESS_PROPERTY, new Integer(10));

addExportedService(VendorService.SERVICE_NAME, service, properties);

}

protected void deactivate() {

LogUtility.logInfo("The Hotdog Vendor bundle has been deactivated"); //$NON-NLS-1$

}

}

//服务的引用

public class Activator extends BaseBundleActivator {

private Customer customer;

//组件启动**

protected void activate() {

LogUtility.logInfo("The Customer bundle has been activated"); //$NON-NLS-1$

VendorService vendor = getVendorService();

Customer customer = getCustomer();

customer.setVendor(vendor);

customer.eat();

}

//组件停止注销

protected void deactivate() {

Customer customer = getCustomer();

customer.setVendor(null);

LogUtility.logInfo("The Customer bundle has been deactivated"); //$NON-NLS-1$

}

private Customer getCustomer() {

return customer;

}

//声明需要引用的服务的名称

protected String[] getImportedServiceNames() {

return new String[] {

VendorService.SERVICE_NAME

};

}

//设定服务过滤条件

private String getVendorFilter() {

StringBuffer buffer = new StringBuffer(50);

buffer.append('(');

buffer.append(VendorService.SPICINESS_PROPERTY);

buffer.append("<="); //$NON-NLS-1$

buffer.append(8);

buffer.append(')');

String filter = buffer.toString();

return filter;

}

//获取HotdogVender服务

private VendorService getVendorService() {

return (VendorService) getImportedService(VendorService.SERVICE_NAME);

}

private void setCustomer(Customer customer) {

this.customer = customer;

}

protected void start() throws Exception {

LogUtility.logInfo("The Customer bundle has been started"); //$NON-NLS-1$

Customer customer = new Customer();

setCustomer(customer);

String filter = getVendorFilter();

addImportedServiceFilter(VendorService.SERVICE_NAME, filter);

}

protected void stop() throws Exception {

setCustomer(null);

LogUtility.logInfo("The Customer bundle has been stopped"); //$NON-NLS-1$

}

}

SAT目前从Eclipse CVS上可以获取到。CVS的访问地址为:

:pserver:dev.eclipse.org:/cvsroot/technology org.eclipse.ohf/plugins/org.eclipse.soda.sat