關於DOSGI-CXF整合到SpringDM上的解決辦法

在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上等等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章