关于DOSGI-CXF整合到SpringDM上的解决办法

来源:互联网 发布:王俊煜 知乎 编辑:程序博客网 时间:2024/06/03 15:27

在osgi的环境下,我们需要RMI的方式调用远端的服务的话,一般有以下的方案。
步骤如下:
服务端发布webserivce,这个我直接摘录网上的资料,代码如:

接口:public interface DisplayService {    boolean displayText(String text);    String getID();}实现类:public class DisplayServiceImpl implements DisplayService {    private final String id;    public DisplayServiceImpl(String id) {        this.id = id;        System.out.println("Created DisplayService [" + id + "]");    }    public boolean displayText(String text) {        System.out.println("DisplayService [" + id + "]: " + text);        return true;    }    public String getID() {        return id;    }}发布服务:public class Activator implements BundleActivator {    private ServiceRegistration reg;     public void start(BundleContext bc) throws Exception {                Dictionary props = new Hashtable();                 String host = getHostName(); // obtain the current host name        int port = getPort();        // find a free port        props.put("service.exported.interfaces", "*");        props.put("service.exported.configs", "org.apache.cxf.ws");        props.put("org.apache.cxf.ws.address", "http://" + host + ":" + port + "/display");        reg = bc.registerService(DisplayService.class.getName(),                 new DisplayServiceImpl(host + ":" + port), props);    }    public void stop(BundleContext bc) throws Exception {        reg.unregister();    }}

客户端代码,如果使用了springDM则配置如下:

第一步:先在OSGI-INF\remote-service目录下配置remote-services.xml内容如下:<?xml version="1.0" encoding="UTF-8"?><endpoint-descriptions xmlns="http://www.osgi.org/xmlns/rsa/v1.0.0">  <endpoint-description>    <property name="objectClass">      <array>        <value>org.apache.cxf.dosgi.samples.springdm.DinnerService</value>      </array>    </property>    <property name="endpoint.id">http://localhost:9000/org/apache/cxf/dosgi/samples/springdm/DinnerService</property>    <property name="service.imported.configs">org.apache.cxf.ws</property>  </endpoint-description></endpoint-descriptions>第二步:在spring配置文件中配置如下:<beans xmlns="http://www.springframework.org/schema/beans"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:osgi="http://www.springframework.org/schema/osgi"  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd                      http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd">  <osgi:reference id="dinnerServiceRef" interface="org.apache.cxf.dosgi.samples.springdm.DinnerService"/>  <bean class="org.apache.cxf.dosgi.samples.springdm.client.DinnerServiceConsumer"        init-method="start">    <property name="dinnerService" ref="dinnerServiceRef"/>  </bean></beans>调用端的代码,如下:public class DinnerServiceConsumer {    DinnerService dinnerService;    public void setDinnerService(DinnerService ds) {        dinnerService = ds;    }    public void start() {        System.out.println("Found the following restaurants:");        for (Restaurant r : dinnerService.findRestaurants("nice and not too expensive!")) {            System.out.format("  %s (%s) Rating: %d\n", r.getName(), r.getAddress(), r.getRating());        }    }}

如果没有使用SpringDM则和普通的OSGI服务发现方式一样,获取webserivce调用服务方式如下:

public class Activator implements BundleActivator {    private ServiceTracker tracker;    private Map<DisplayService, String> displays = new ConcurrentHashMap<DisplayService, String>();    private ScheduledExecutorService scheduler;    private ScheduledFuture<?> handle;    public void start(BundleContext bc) throws Exception {        tracker = new ServiceTracker(bc, DisplayService.class.getName(), null) {            public Object addingService(ServiceReference reference) {                Object svc = super.addingService(reference);                if (svc instanceof DisplayService) {                    DisplayService d = (DisplayService) svc;                    System.out.println("Adding display: " + d.getID() + " (" + d + ")");                    displays.put(d, d.getID());                }                return svc;            }            public void removedService(ServiceReference reference, Object service) {                String value = displays.remove(service);                System.out.println("Removed display: " + value);                super.removedService(reference, service);            }        };        tracker.open();        scheduler = Executors.newScheduledThreadPool(1);        Runnable printer = new Runnable() {            int counter;            public void run() {                counter++;                String text = "some text " + counter;                System.out.println("Sending text to displays: " + text);                for (Entry<DisplayService, String> entry : displays.entrySet()) {                    try {                        entry.getKey().displayText(text);                    } catch (Throwable th) {                        System.out.println("Could not send message to display: " + entry.getValue());                    }                }            }        };        handle = scheduler.scheduleAtFixedRate(printer, 5, 5, TimeUnit.SECONDS);    }    public void stop(BundleContext bc) throws Exception {        handle.cancel(true);        tracker.close();    }}

注意,一定要加入cxf-dosgi-ri-discovery-local-xxx.jar这个jar包以及其他相关的包,具体可以参考网站:
http://cxf.apache.org/dosgi-discovery-demo-page.html,而且我这个也是参考官方的例子,如果要参考比较全的例子,可以下载官方的源码,里边的samples下有各种例子,比如如何使用spring-dm整合,如何发布到zookeeper上等等。

0 0