升级CXF至3.1.2后Spring4.1.8下EndpointImpl实例化失败求助
解决CXF 3.1.2与Spring 4.1.8兼容的EndpointImpl实例化问题
我之前也踩过类似的版本兼容坑,CXF 3.1.x开始对Spring的版本依赖做了调整,默认的SpringEndpointImpl用到了Spring 4.2才支持的构造函数注入特性,而Spring 4.1.8无法处理这种无默认构造函数的bean实例化;再加上你注释了CXF的核心配置文件,相当于把CXF的基础运行环境给拆了,问题自然就爆发了。下面给你一步步的解决方案:
1. 恢复CXF核心配置文件
首先把你注释掉的配置加回去,这是CXF正常工作的基础,绝对不能删:
<import resource="classpath:META-INF/cxf/cxf.xml"/> <import resource="classpath:META-INF/cxf/cxf-servlet.xml"/> <!-- 若是Web项目,这个也得加上 -->
这些文件配置了CXF的总线(Bus)、端点工厂等核心组件,没有它们CXF根本没法启动。
2. 自定义兼容Spring 4.1的EndpointImpl子类
创建一个自定义的Endpoint子类,提供Spring 4.1能够识别的构造函数,绕过对Spring 4.2的依赖:
import org.apache.cxf.jaxws.EndpointImpl; import org.springframework.context.ApplicationContext; public class Spring41CompatibleEndpointImpl extends EndpointImpl { // 显式提供ApplicationContext + 实现类的构造函数,Spring 4.1可以正常注入 public Spring41CompatibleEndpointImpl(ApplicationContext context, Object implementor) { super(context, implementor); } }
3. 在Spring配置中指定使用自定义Endpoint类
如果是XML配置方式
修改你的jaxws端点配置,通过class属性指定我们自定义的类:
<jaxws:endpoint id="myWebService" implementor="com.yourpackage.YourActualWebServiceImpl" address="/myWebService" class="com.yourpackage.Spring41CompatibleEndpointImpl"/>
如果是Java Config方式
直接在@Bean方法中实例化自定义的Endpoint:
import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WebServiceConfig { @Bean public Endpoint myWebService(ApplicationContext context, YourActualWebServiceImpl implementor) { Spring41CompatibleEndpointImpl endpoint = new Spring41CompatibleEndpointImpl(context, implementor); endpoint.publish("/myWebService"); return endpoint; } }
4. 调整获取Endpoint的代码
现在你可以正常获取这个自定义的Endpoint实例了,类型转换的时候注意改成我们的自定义类(或者直接用父类Endpoint,如果不需要子类特有的方法的话):
// 方式1:用自定义类转换 Spring41CompatibleEndpointImpl myWSImpl = (Spring41CompatibleEndpointImpl)Boot.getAppContext().getBean("myWebService"); // 方式2:如果只需要Endpoint的通用方法,直接用父类更安全 Endpoint myWSImpl = (Endpoint)Boot.getAppContext().getBean("myWebService");
原理很简单:CXF默认的SpringEndpointImpl用了Spring 4.2新增的构造函数参数解析逻辑,Spring 4.1无法自动匹配合适的构造函数,我们自定义子类显式提供一个Spring 4.1能处理的构造函数,就能让容器正常实例化了。
内容的提问来源于stack exchange,提问作者Shubh
相关产品推荐
相关产品推荐

