Apache CXF 分布式OSGi部署HelloWorld


摘要

要配置Apache CXF OSGi的部署其實比較簡單,但是我們一般都會在網上找資料,會遇到怎么也發現不了服務的情況,讓人都很郁悶。

有了這次的經歷,我要看官方的文檔,以防上當。

一、環境准備

首先下載Apache CXF 的包,下載地址:http://cxf.apache.org/dosgi-releases.html

我們下載下面這兩個就可以了,我們這次會用到cxf-dosgi-ri-singlebundle-distribution

Multi-bundle distribution (zip)
cxf-dosgi-ri-multibundle-distribution-1.3.1-dir.zip

Single-bundle distribution
cxf-dosgi-ri-singlebundle-distribution-1.3.1.jar

目前需要3個bundle

image

注意版本號

導入cxf-dosgi-ri-singlebundle-distribution-1.3.1.jar 包,在Eclipse中菜單:File->import,選擇如下圖所示

image

選擇文件所在的路徑

image

image

我們會在Package Explorer視圖中看到

image

好了,我們的開發環境就配置好了。

二、創建演示程序-生產服務

創建HelloWorld演示程序

Eclipse->File->new->project-

image

image

image

我們就寫一個helloworld的接口

代碼如下:

public interface HelloWorldService {
	String sayHello();
}
接下來我們用同樣的方法來,做一個HelloworldService的實現工程

Eclipse->File->new->project

image

image

image

我們來寫一個實現類如下,首先添加對接口的依賴

image

實現類如下:

public class HelloWorldServiceImpl implements HelloWorldService {

	@Override
	public String sayHello() {
		System.out.println("HelloWorld");
		return (new Date()).toString();
	}
}
現在實現類有了,我們現在要注冊成web服務,打開實現工程中的Activator類,注冊服務代碼如下:
public class Activator  implements BundleActivator {

	@SuppressWarnings("rawtypes")
	private ServiceRegistration registration;
	private static BundleContext context;

	static BundleContext getContext() {
		return context;
	}
	@Override
	public void start(BundleContext bundleContext) throws Exception {
		Activator.context = bundleContext;
		//設置服務的屬性
    	Dictionary<String, String> props = new Hashtable<String, String>();

	    props.put("service.exported.interfaces","*");  
	    props.put("service.exported.intents","SOAP");  
	    props.put("service.exported.configs","org.apache.cxf.ws");  
	    props.put("org.apache.cxf.ws.address","http://localhost:9000/hello_world");  

        //注冊服務
        registration = Activator.context.registerService(HelloWorldService.class.getName(), new HelloWorldServiceImpl(), props);
	}

	@Override
	public void stop(BundleContext bundleContext) throws Exception {
		Activator.context = null;
		 registration.unregister();
	}

}
好了,我們的服務已經注冊成功了,我們看看在瀏覽器中是什么樣子的,
Eclipse-Run->Run configuration,配置結果如下圖所示:
image
點擊run后我們可以看到如下日志:
image
這就說明了我的web服務已經注冊成功了,好了,我們在瀏覽器中看一下結果,在瀏覽器中輸入:http://localhost:9000/hello_world?wsdl,就可以看到如下結果
image
接下來我們會消費服務

三、消費服務

我們建一個插件工程,命名為:HelloWorldClient,創建好以后如下:

image

我們要使用服務就要先引用依賴組件,如下圖所示

image

我們還要配置一下服務的發現,在工程下建立OSGI-INF文件夾,里面新建一個remote-service文件夾,在remote-service新建一個remote-services.xml,該文件內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<service-descriptions xmlns="http://www.osgi.org/xmlns/sd/v1.0.0">
  <!--遠程服務描述-->
  <service-description>
    <!--定義遠程服務映射到本地的服務的接口 -->
    <provide interface="helloworldservice.HelloWorldService" />
    <!-- 遠程服務的接口 -->
    <property name="service.exported.interfaces">*</property>
    <!-- 遠程服務的形式 -->
    <property name="service.exported.intents">SOAP</property>
    <!-- 服務的類型-->
    <property name="service.exported.configs">org.apache.cxf.ws</property>
    <!-- 服務的地址-->
    <property name="org.apache.cxf.ws.address">http://localhost:9000/hello_world</property>
  </service-description>
</service-descriptions>

和我們在實現類里面注冊服務的代碼一樣

我們來看一下HelloWorldClient的Activator類的內容,主要的內容就是獲取服務,然后調用服務,很簡單。

public class Activator implements BundleActivator {
	@SuppressWarnings("rawtypes")
	private ServiceTracker tracker;
	private static BundleContext context;

	static BundleContext getContext() {
		return context;
	}
	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public void start(BundleContext bundleContext) throws Exception {
		Activator.context = bundleContext;
		//創建ServiceTracker,捕獲HelloWorldService添加到OSGi框架的事件
        tracker = new ServiceTracker(Activator.context, HelloWorldService.class.getName(), null) {
            @Override
        	public Object addingService(ServiceReference reference) {
                Object result = super.addingService(reference);
                //獲取服務
                HelloWorldService helloWorldService = (HelloWorldService)Activator.context.getService(reference);
                //使用服務
                System.out.println("call say hello at " + helloWorldService.sayHello());               
                return result;
            }
        };
        tracker.open();
	}

	/*
	 * (non-Javadoc)
	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
	 */
	public void stop(BundleContext bundleContext) throws Exception {
		Activator.context = null;
		System.out.println("hello world client close");
		tracker.close();
	}

}
好了,我們的消費者就創建好了,來看一下運行效果吧
先進行運行 配置,如下圖所示
image
image
我們在上圖中可以看到結果
 
好了,我們的演示已經結束了,看起來還是比較簡單的,但是在做的過程中還是遇到一些問題,比如使用了老的注冊服務代碼如下:
  props.put("osgi.remote.interfaces", "*");
        props.put("osgi.remote.configuration.type", "pojo");
        props.put("osgi.remote.configuration.pojo.address", "http://localhost:9000/hello_world");

使用這個代碼是注冊服務不成功的,請大家注意!

源碼下載:下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM