原创作者: jnn   阅读:9357次   评论:5条   更新时间:2011-05-26    

最近在cxf-zh中有人问及了有关Spring配置CXF Client以及Server的问题,由于我前段时间也做一部分相关的工作,在这里我简单给大家介绍一下CXF在与Spring集成方面所做的一些工作。

如果大家只是想了解如何写jaxws:endpoint 配置文件,可以直接跳到 3 jaxws:endpoing进行阅读.

0. 预备知识

如果你想了解CXF是如何与Spring进行集成的,首先你需要下载CXF代码,编译,然后生成相关的Eclipse工程文件。

具体的步骤在CXF wiki 上有说明

1. 基本原理

CXF采用的是Spring2.0提供的一个新接口就是扩展的NamespaceHandler。通过注册相关的NamespaceHandler以及xsd,在Spring处理到对应Namespace下的XML元素时将会调用NamespaceHandler中注册的Parser来进行处理。

瞧是不是挺简单的。

具体代码位置 Project: cxf-rt-frontend-jaxws

源代码 src/main/java Package org.apache.cxf.jaxws.spring

测试 src/test/java Package org.apache.cxf.jaxws.spring

schema: jaxws.xsd src/main/resources schemas

2. jaxws namespace

在jaxws.xsd中,你将看到有关 jaxws:endpoint, jaxws:server, jaxws:client的定义。

这里需要说明的内容有三点:
  1. jaxws的target namespace是 http://cxf.apache.org/jaxws,由于目前CXF还处于incubating 的状态,没有cxf.apache.org这个域名。为了能让Spring来进行xml文档校验的时候能够获得jaxws.xsd,Spring提供了一种通过ClassPath中获得jaxws.xsd方法。具体步骤如下就是在META-INF中添加spring.schema的方式将jaxws.xsd与对应的URI进行绑定,同时也需要将NamespaceHandler注册进Spring中。
  2. jaxws:endpoint 与 jaxws:server是对等的,他们都是对Web Services 服务端的描述。只是在JAXWS RI在最初的实现过程中,对于Server端的配置是通过Endpoint来进行描述的,而且JAXWS API也定义了Endpoint,因此为了保持与JAXWS API的一致性,在这里设置了jaxws:endpoint。
  3. jaxws front end 与 simple front end之间的关系。 CXF除了提供JAXWS 的实现,也延续Xfire的风格提供了简单POJO Web Services的实现前端 simple front end。Jaxws front end 继承了simple front end的绝大部分方法,它与simple front end 的最大不同就是提供了Web Services Meta data (JSR 181)的支持,提供从Annotation中获取Web Services的能力。对于 jaxws:server 以及 jaxws:client 你可以在 simple front end中找到对应的 simple:server , simple:client。

3. jaxws:endpoint示例

我们知道Spring为我们提供了一个很好的Dependence Injection的容器,我们可以通过XML在不修改任何Java Code的情况下,通过配置改变Spring beans 之间的属性。下面是endpoint的 schema,我们将结合schema向大家介绍有关spring的配置和使用。
xml 代码
  1. <xsd:schema xmlns="http://cxf.apache.org/jaxws"
  2. xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  3. xmlns:beans="http://www.springframework.org/schema/beans"
  4. xmlns:cxf-beans="http://cxf.apache.org/configuration/beans"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. targetNamespace="http://cxf.apache.org/jaxws"
  7. elementFormDefault="qualified"
  8. attributeFormDefault="unqualified" >
  9. <xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="http://www.springframework.org/schema/beans/spring-beans.xsd"/>
  10. <xsd:import namespace="http://cxf.apache.org/configuration/beans" schemaLocation="http://cxf.apache.org/schemas/configuration/cxf-beans.xsd"/>
  11. <xsd:element name="endpoint">
  12. <xsd:complexType>
  13. <xsd:complexContent>
  14. <xsd:extension base="beans:identifiedType">
  15. <xsd:all>
  16. <xsd:element name="binding" type="xsd:anyType" minOccurs="0" />
  17. <xsd:element name="dataBinding" type="xsd:anyType" minOccurs="0" />
  18. <xsd:element name="executor" type="xsd:anyType" minOccurs="0" />
  19. <xsd:element name="features" type="xsd:anyType" minOccurs="0" />
  20. <xsd:element name="implementor" type="xsd:anyType" minOccurs="0" />
  21. <xsd:element name="inInterceptors" type="xsd:anyType" minOccurs="0" />
  22. <xsd:element name="inFaultInterceptors" type="xsd:anyType" minOccurs="0" />
  23. <xsd:element name="invoker" type="xsd:anyType" minOccurs="0" />
  24. <xsd:element name="outInterceptors" type="xsd:anyType" minOccurs="0" />
  25. <xsd:element name="outFaultInterceptors" type="xsd:anyType" minOccurs="0" />
  26. <xsd:element name="properties" type="beans:mapType" minOccurs="0" />
  27. <xsd:element name="schemaLocations" type="schemasType" minOccurs="0" />
  28. <xsd:element name="serviceFactory" type="xsd:anyType" minOccurs="0" />
  29. <!--</span-->xsd:all>
  30. <xsd:attributeGroup ref="cxf-beans:beanAttributes" />
  31. <xsd:attribute name="address" type="xsd:string" />
  32. <xsd:attribute name="bindingUri" type="xsd:string" />
  33. <xsd:attribute name="bus" type="xsd:string" />
  34. <xsd:attribute name="implementor" type="xsd:string"/>
  35. <xsd:attribute name="implementorClass" type="xsd:string"/>
  36. <xsd:attribute name="publish" type="xsd:boolean" default="true"/>
  37. <xsd:attribute name="endpointName" type="xsd:QName" />
  38. <xsd:attribute name="serviceName" type="xsd:QName" />
  39. <xsd:attribute name="wsdlLocation" type="xsd:string" />
  40. <!--</span-->xsd:extension>
  41. <!--</span-->xsd:complexContent>
  42. <!--</span-->xsd:complexType>
  43. <!--</span-->xsd:element>
  44. <!--</span-->xsd:schema>

这里设置的endpoint中的很多子元素都定义成为了 xsd:anyType, 这是为了能通过原有Spring bean的方式来初始化具体的实例。例如: implementor 这个子元素。

xml 代码
  1. <jaxws:endpoint id="inlineImplementor" address="http://localhost:8080/simpleWithAddress">
  2. <jaxws:implementor>
  3. <bean class="org.apache.hello_world_soap_http.GreeterImpl">
  4. <property name="prefix" value="hello" />
  5. <!--</span-->bean>
  6. <!--</span-->jaxws:implementor>
  7. <!--</span-->jaxws:endpoint>

当然对于properties来说,就是采用了spring中内建的Map类型的支持,具体的使用实例如下:

xml 代码
  1. <jaxws:endpoint id="withProerties" implementor="org.apache.hello_world_soap_http.GreeterImpl" address="http://localhost:8080/simpleWithAddress">
  2. <jaxws:properties>
  3. <entry key="Content-Type" value="text/plain" />
  4. <entry>
  5. <key>
  6. <value>javax.xml.stream.XMLInputFactory<!--</span-->value>
  7. <!--</span-->key>
  8. <ref bean="mappedXMLInputFactory"/">
  9. <!--</span-->entry>
  10. <entry>
  11. <key>
  12. <value>javax.xml.stream.XMLOutputFactory<!--</span-->value>
  13. <!--</span-->key>
  14. <ref bean="mappedXMLOutputFactory"/">
  15. <!--</span-->entry>
  16. <!--</span-->jaxws:properties>
  17. <!--</span-->jaxws:endpoint>

好现在看一下如何配置属性(attribute) jaxws:endpoint 也提供了对 implementor描述的属性, 当我们将 implementor定义成为一个java class时我们可以这样写

xml 代码
  1. <jaxws:endpoint id="implementor" implementor="org.apache.hello_world_soap_http.GreeterImpl" address="http://localhost:8080/simpleWithAddress"/>

 

当我们考虑将implementor定义成为一个bean的引用,就应该写成

xml 代码
  1. <jaxws:endpoint id="implementor" implementor="#GreeterImpl" address="http://localhost:8080/simpleWithAddress"/>

这里再讲一下endpointName和serviceName的写法,大家可以看到这两个属性的类型都是Qname

xml 代码
  1. <jaxws:endpoint id="withEndpiontName" implementor="org.apache.cxf.jaxws.service.Hello" endpointname="e:HelloEndpointCustomized" servicename="s:HelloServiceCustomized" address="http://localhost:8080/test" />

 

4. EndpointDefinitionParser

看了上面的jaxws:endpoint 示例,大家可能会向CXF是如何将这些XML文件映射成为具体的 Jaxws Endpoint 呢? 有心的朋友只要看一下 EndpointDefinitionParser 就能略知一二了。

请注意 EndpointDefinitionParser的构造函数,里面调用了setBeanClass(EndpointImpl.class);当当我们的要设置的主角终于登场了。 再则就是 protected void doParse(Element element, ParserContext ctx, BeanDefinitionBuilder bean),如果你要配置自己的Bean对象,就需要花点功夫在这个函数上面了。

今天的介绍先到这,有兴趣的朋友可以用同样的方法来研究有关 jaxws:server以及jaxws:client的具体实现,还有我会在后面的文章中介绍在CXF中有关doParser的更为复杂的实现。

评论 共 5 条 请登录后发表评论
5 楼 qingyingyisheng 2011-09-21 13:08
      
4 楼 rrsy23 2010-07-31 11:41
先看看 spring的文档中讲  NamespaceHandler把文档例子跑起来

然后自己写一个简单的NamespaceHandler 把自己的服务集成到spring配置里面

现在太多这样的了

step by step
3 楼 shadowsese 2010-07-30 11:13
讲的深入且到位,赞一下
2 楼 prettyboy434 2010-07-21 17:36
我刚接触cxf,有点看不懂
1 楼 haiyupeter 2010-06-23 20:05
这篇文章不错,讲得比较深入一些,赞一个。

发表评论

您还没有登录,请您登录后再发表评论

文章信息

Global site tag (gtag.js) - Google Analytics