在osgi规范R4.2版本中,定义了分布式的osgi。distribution-cxf是这个规范的一个实现。利用d-cxf可以在osgi环境发布出标准的web service,同样在osgi环境中,也可以引用标准的web service。在distribution-cxf的官方网站中,有几个这样的例子。这里,对于利用spring dm实现的dosgi进行分析
这个demo中,包含了三个bundle:cxf-dosgi-ri-samples-spring-dm-interface,cxf-dosgi-ri-samples-spring-dm-impl,cxf-dosgi-ri-samples-spring-dm-client。
在第一个bundle中定义了要发布的web service的接口,将被export出来,供其他两个bundle应用。DinnerService interface的定义如下:
import java.util.List;
public interface DinnerService {
List<Restaurant> findRestaurants(String searchQuery);
public String testService();
}
在第二个bundle中,一是实现了第一个bundle中定义的接口,更重要的是利用springdm把这个实现发布为一个web service。和利用springdm定义发布出osgi注册服务的定义相同,都是利用osgi:service标签,完成service的发布。
<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:service interface="org.apache.cxf.dosgi.samples.springdm.DinnerService"> <osgi:service-properties> <entry key="service.exported.interfaces" value="*" /> <entry key="endpoint.id" value="http://localhost:9000/org/apache/cxf/dosgi/samples/springdm/DinnerService"/> </osgi:service-properties> <bean class="org.apache.cxf.dosgi.samples.springdm.impl.DinnerServiceImpl" /> </osgi:service> </beans>
这个配置文件,同样放在META-INF/spring的目录下,之所以它能够被发布成为一个标准的WebService,是因为在osgi的环境中,除了启动了springdm的bundle,还启动了d-cxf的bundle,这些bundle在springdm的基础上,把这个service发布出来。d-cxf的bundle有两种组织形式,一是单一bundle形式,d-cxf把所有有关的bundle整合成一个bundle,供具体的应用加载;另一种方式是按照d-cxf的依赖,分成多个bundle,两种方式没有本职的区别。
cxf-dosgi-ri-samples-spring-dm-client是在osgi的环境中对上一个实现中发布的web service进行引用,在META-INF/spring目录下,有一个利用springdm引用bundle服务的标准的配置文件:
<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="test">
<property name="dinnerService" ref="dinnerServiceRef"/>
</bean>
</beans>
为了在分布的环境中引用WebService,就需要知道另外的一个进程中的service的发布情况和如何应用它,于是,在client bundle中,加入了一个目录OSGI-INF,在其中的remote-service目录,定义了对于远程服务的应用配置:
<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://169.254.78.194:9000/org/apache/cxf/dosgi/samples/springdm/DinnerService</property> <property name="service.imported.configs">org.apache.cxf.ws</property> </endpoint-description> </endpoint-descriptions>
对于熟悉ServiceMix的人,endpoint一定是一个非常熟悉的概念,事实上d-cxf中ServiceMix的一些bundle来管理在dosgi环境中WebService发布和应用的。