摘要
要配置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
注意版本號
導入cxf-dosgi-ri-singlebundle-distribution-1.3.1.jar 包,在Eclipse中菜單:File->import,選擇如下圖所示
選擇文件所在的路徑
我們會在Package Explorer視圖中看到
好了,我們的開發環境就配置好了。
二、創建演示程序-生產服務
創建HelloWorld演示程序
Eclipse->File->new->project-
我們就寫一個helloworld的接口
代碼如下:
public interface HelloWorldService { String sayHello(); }接下來我們用同樣的方法來,做一個HelloworldService的實現工程
Eclipse->File->new->project
我們來寫一個實現類如下,首先添加對接口的依賴
實現類如下:
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,配置結果如下圖所示:
點擊run后我們可以看到如下日志:
這就說明了我的web服務已經注冊成功了,好了,我們在瀏覽器中看一下結果,在瀏覽器中輸入:http://localhost:9000/hello_world?wsdl,就可以看到如下結果
接下來我們會消費服務
三、消費服務
我們建一個插件工程,命名為:HelloWorldClient,創建好以后如下:
我們要使用服務就要先引用依賴組件,如下圖所示
我們還要配置一下服務的發現,在工程下建立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(); } }
好了,我們的消費者就創建好了,來看一下運行效果吧
先進行運行 配置,如下圖所示
我們在上圖中可以看到結果
好了,我們的演示已經結束了,看起來還是比較簡單的,但是在做的過程中還是遇到一些問題,比如使用了老的注冊服務代碼如下:
props.put("osgi.remote.interfaces", "*"); props.put("osgi.remote.configuration.type", "pojo"); props.put("osgi.remote.configuration.pojo.address", "http://localhost:9000/hello_world");
使用這個代碼是注冊服務不成功的,請大家注意!
源碼下載:下載