Spring apache camel apache cxf IllegalStateException:无法在bean名称';cxf';:已经存在对象绑定
骆驼版本:2.12.2, CXF版本:2.7, ApacheTomcat:7 我有以下camel-cxf.xml文件:Spring apache camel apache cxf IllegalStateException:无法在bean名称';cxf';:已经存在对象绑定,spring,queue,cxf,apache-camel,illegalstateexception,Spring,Queue,Cxf,Apache Camel,Illegalstateexception,骆驼版本:2.12.2, CXF版本:2.7, ApacheTomcat:7 我有以下camel-cxf.xml文件: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:s0="http://www.huawei.com/bme/cbsinterface/cbs/bus
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:s0="http://www.huawei.com/bme/cbsinterface/cbs/businessmgr"
xmlns:s1="http://www.huawei.com/bme/cbsinterface/cbs/accountmgr"
xmlns:cxf="http://camel.apache.org/schema/cxf"
xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://cxf.apache.org/transports/http/configuration http://cxf.apache.org/schemas/configuration/http-conf.xsd
http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd">
<bean id="loggingInInterceptor" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
<bean id="loggingOutInterceptor" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />
<cxf:cxfEndpoint id="oneEndpoint"
address="${endpoint.address}"
serviceName="s1:WebService"
serviceClass="WebserviceClass"
endpointName="s1:WebSericePort_http"
wsdlURL="classpath:wsdl/WebService.wsdl">
<cxf:inInterceptors>
<ref bean="loggingInInterceptor" />
<ref bean="setSoapVersionInterceptor"/>
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
<ref bean="loggingInInterceptor" />
<ref bean="setSoapVersionInterceptor"/>
</cxf:inFaultInterceptors>
<cxf:outInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
<ref bean="loggingOutInterceptor" />
</cxf:outFaultInterceptors>
</cxf:cxfEndpoint>
<http-conf:conduit name="*.http-conduit">
<http-conf:client
Connection="Keep-Alive"
ConnectionTimeout="60000"
ReceiveTimeout="90000"/>
</http-conf:conduit>
</beans>
可在此处找到完整的stacktrace:
当队列第二次同时收到消息时,一切正常
有什么想法吗
另外,My web.xml是:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:/META-INF/spring/*.xml</param-value>
</context-param>
</web-app>
org.springframework.web.context.ContextLoaderListener
上下文配置位置
classpath*:/META-INF/spring/*.xml
路由和处理器:
<route id="route1" errorHandlerRef="eh1">
<from uri="{{queue1}}" />
<setHeader headerName="operationName">
<constant>Operation_1</constant>
</setHeader>
<process ref="FirstProcessor" />
<choice>
<when>
<simple>${in.headers.STATUS} == 'OK'</simple>
<inOnly uri="{{result_queue}}" />
</when>
<otherwise>
<inOnly uri="{{nok_result_queue}}" />
</otherwise>
</choice>
</route>
<route id="route2" errorHandlerRef="eh2">
<from uri="{{queue2}}" />
<setHeader headerName="operationName">
<constant>Operation_2</constant>
</setHeader>
<process ref="SecondProcessor" />
<choice>
<when>
<simple>${in.headers.STATUS} == 'OK'</simple>
<inOnly uri="{{result_queue}}" />
</when>
<otherwise>
<inOnly uri="{{nok_result_queue}}" />
</otherwise>
</choice>
</route>
行动1
${in.headers.STATUS}=='OK'
行动2
${in.headers.STATUS}=='OK'
请共享使用来自两个不同队列的消息的路由定义。您还可以寻找使用多播的选项,以便在使用来自两个队列的消息时进行并行处理,并继续执行进一步的操作。
直接:${header.operationName}
您的路由(route1和route)可以重命名为与webservice操作名称相同的名称。我们的代码也与您的代码类似。我们没有遇到这种方法的问题。问题是,两个队列都在同一时间获取消息,因此它们都试图同时初始化SpringBus 问题在于,在BusWiringBeanFactoryPostProcessor中,它包含以下代码:
if (!context.containsBean(name) && (create || Bus.DEFAULT_BUS_ID.equals(name))) {
SpringBus b = new SpringBus();
ConfigurableApplicationContext cctx = (ConfigurableApplicationContext)context;
cctx.getBeanFactory().registerSingleton(name, b);
b.setApplicationContext(context);
}
因此,当两个bean都尝试在两个不同的线程中初始化SpringBus时,它们都可以同时输入if语句,从而导致异常
解决方案是在应用程序上下文中定义一个SpringBus,这样两个bean都不会尝试创建一个新的SpringBus,因为它已经存在。如果最初只有一个队列获得一条消息,那么程序会工作吗?听起来好像两个队列同时收到一条消息,所以两个队列都在尝试进行初始化,而您的队列在某个地方遇到了线程问题。是的,这是可能的。然而,即使我添加了两个不同的cxf端点,它们除了ID之外都具有完全相同的配置,我也会得到完全相同的错误。因此,我不确定如何解决这个问题。部署时没有办法注册端点吗?添加两个不同的cfx端点不会有帮助,因为问题是初始化它们之间共享的底层SpringBus。您可以发布带有异常行号的完整堆栈跟踪吗?解决方法可能是显式定义SpringBusBean并将其添加到上下文中。将其添加为答案,以便我可以接受。:)我使用两条路由,它们使用两个不同的队列和两个不同的处理器。因此,您的解决方案似乎不合适。请查看我对路由和处理器的编辑。您也可以尝试这样的操作
${body}!=空直接:${header.operationName}
<property name="producerTemplate" ref="firstProcessorTemplate" />
<property name="producerTemplateUri"
value="cxf:bean:oneEndpoint?headerFilterStrategy=#headerFilterStrategy" />
<property name="producerTemplate" ref="secondProcessorTemplate" />
<property name="producerTemplateUri"
value="cxf:bean:oneEndpoint?headerFilterStrategy=#headerFilterStrategy" />
if (!context.containsBean(name) && (create || Bus.DEFAULT_BUS_ID.equals(name))) {
SpringBus b = new SpringBus();
ConfigurableApplicationContext cctx = (ConfigurableApplicationContext)context;
cctx.getBeanFactory().registerSingleton(name, b);
b.setApplicationContext(context);
}