讨论:
1、 关于CXF的Bus:
CXF中的Bus是CXF中的核心部件,并不是我们传统上提到的通讯层面的总线,而更像一个公共服务和组件的存放仓库。这有点类似Corba中的命名服务或是JEE环境下的JDNI注册树。它使用JAVA类的meta类做为查找索引,缺省情况下,注册了如下几个核心类:
a) CXFBusLifeCycleManager类,实现observer模式,用于发送Bus的起停事件;
b) DestinationFactoryManager类,传输层的发送端口抽象类,用于创建SOAP消息发送通道;
c) ResourceManager类,资源读取工具,主要读取配置文件,WSDL文件等;
d) ConduitInitiatorManager类,传输层的接收端口抽象类,用于创建SOAP消息的接收通道;
e) BindingFactoryManager类,SOAP绑定工厂类,实现JAXWS2.1规范要求;
2、关于OSGI环境下类的可见性问题
OSGI中的每个Bundle都是使用独立的类装载器;类装载器本身就为其装载的类创建了一个无形的名字空间,因此即使是相同的类,被不同的装载器装载后,彼此也变成的了不同的类。所以在开发OSGI应用的时候经常要主要此类的问题的发生,特别是当出现ClassCastException和classDefinitionNotFound的时候要特别警惕是否是由于类装载器引入的问题。这里举一个稍微复杂的例子:
在前面清理CXF的第三方库中,我曾经单独提到Javax.ws的库在JDK6的环境下要从CXF的lib目录下移除。现在看看如果不移掉,会有什么问题:
首先JDK6中已经定义了Javax.ws,在JVM启动后,它就被缺省的类装载器装载。那么WebService Bundle缺省情况下也将使用JVM的Javax.ws库。而CXF Bundle则不同,它自己的类装载器装载了另外一套Javax.ws库(Bundle中的类搜索优先级别是先Bundle自己的classpath,然后才是外部的)。所以当WebService Bundle通过CXF Bundle暴露的OSGI服务注册WebService时,接口类上的annotation @WebService(注意这个annotation使用的是JVM的Javax.ws)对于CXF Bundle就是不可见的,于是从CXF Bundle的角度来看,客户端提供了一个纯的,没有任何annotation修饰的类,同时这个类也没有提供任何WSDL文件的信息,最终导致注册失败。