[转]CXF脱离Spring运行

CXF和Spring结合的非常紧密,默认发布Server端是需要用到Spring的,但是项目中用到的Spring jar包比较老2.0,CXF版本2.3.1,跟Spring不兼容,需要换乘Spring2.5,但是换jar包对原来的项目存在风险,上网搜了一个脱 离Spring运行的方法。

 

写一个类继承CXFNonSpringServlet,重写loadBus方法。


 1  @SuppressWarnings( " unchecked " )
 2       public   void  loadBus(ServletConfig servletConfig)  throws  ServletException {
 3           super .loadBus(servletConfig);
 4          Bus bus  =   this .getBus();
 5          BusFactory.setDefaultBus(bus);
 6          
 7          Enumeration < String >  enums  =  getInitParameterNames();
 8           while  (enums.hasMoreElements()) {
 9              String key  =  enums.nextElement();
10              String value  =  getInitParameter(key);
11               try  {
12                  Class clz  =  Class.forName(value);
13                   try  {
14                      Endpoint.publish(key, clz.newInstance());
15                  }  catch  (InstantiationException e) {
16                      e.printStackTrace();
17                  }  catch  (IllegalAccessException e) {
18                      e.printStackTrace();
19                  }
20              }  catch  (ClassNotFoundException e) {
21                  e.printStackTrace();
22              }
23          }
24      }

在web.xml里将要发布的类配置一下,可以配置多个

 1       < servlet >   
 2                < servlet-name > CXFServlet </ servlet-name >   
 3                < servlet-class >   
 4                    com.infodms.ws.util.MyCXFNoSpringServlet  
 5                </ servlet-class >   
 6                < init-param >   
 7                   < param-name > /TestService </ param-name >   
 8                   < param-value > com.infodms.ws.test.TestServiceImpl </ param-value >   
 9                </ init-param >   
10                < init-param >   
11                   < param-name > /HelloWorld </ param-name >   
12                   < param-value > com.infodms.ws.test.HelloWorldImpl </ param-value >   
13                </ init-param >   
14            </ servlet >   
15            < servlet-mapping >   
16                < servlet-name > CXFServlet </ servlet-name >   
17                < url-pattern > /ws/* </ url-pattern >   
18            </ servlet-mapping >  

配置完成,启动tomcat,报错,还是加载了spring,但是代码确实走了刚刚加的MyCXFNoSpringServlet

1      java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.apache.cxf.bus.spring.BusApplicationListener' defined in class path resource [META-INF/cxf/cxf.xml]: Initialization of bean failed; nested exception is java.lang.NoSuchMethodError: org.springframework.context.support.AbstractApplicationContext.addApplicationListener(Lorg/springframework/context/ApplicationListener;)V  
2          org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:96) 

调试了一下源码,内部需要从环境变量中取得org.apache.cxf.bus.factory的值,如果为空就默认按照spring的方式加载。于是在类的最开始加入一行代码

1  System.setProperty( " org.apache.cxf.bus.factory " " org.apache.cxf.bus.CXFBusFactory " ); 

再次启动tomcat,报错,由异常可知WoodstoxValidationImpl类没有默认构造方法,通过反射实例化对象报错,看了一下这个类的源码,确实没有无参构造方法

1      Caused by: java.lang.InstantiationException: org.apache.cxf.wstx_msv_validation.WoodstoxValidationImpl   
2              at java.lang.Class.newInstance0(Class.java: 340 )   
3              at java.lang.Class.newInstance(Class.java: 308 )   
4              at org.apache.cxf.bus.extension.Extension.load(Extension.java: 110 )  


http://cxf.547215.n5.nabble.com/jira-Created-CXF-3077-java-lang-InstantiationException-org-apache-cxf-wstx-msv-validation-WoodstoxVal-td3228305.html

引用这个,加入三个jar包

woodstox-core-asl-4.0.8.jar 
stax2-api-3.0.2.jar
msv.jar

 

问题解决。

原文出自:
http://liuqiang5151.iteye.com/blog/840496

你可能感兴趣的:([转]CXF脱离Spring运行)