问题描述
我试图了解基于 Camel 的 bean 和 spring 远程处理。
我创建了两个项目:
服务器端接口是 DeliveryService,它由 DeliveryServiceImpl 类实现,该类有两个方法重载,方法签名不同。列出以下代码后,独立服务器运行没有任何问题。
String updateDelivery(String address);
String updateDelivery(String address,String zipCode);
在客户端,包含接口,并注入到实际调用该方法的 bean 中。下面是那个的xml配置。
<camel:proxy id="deliveryService" serviceInterface="com.remote.client.DeliveryService" serviceUrl="direct:input"/>
<bean id="deliveryInfo" class="com.remote.client.UpdateDeliveryDetailsFromClient">
<property name="deliveryService" ref="deliveryService" />
</bean>
现在,当我执行客户端时,我看到服务器端被调用但收到 Ambiguous method invocation
异常。
org.apache.camel.component.bean.AmbiguousMethodCallException: Ambiguous method invocations possible: [public java.lang.String com.springremote.srvr.DeliveryServiceImpl.updateDelivery(java.lang.String),public java.lang.String com.springremote.srvr.DeliveryServiceImpl.updateDelivery(java.lang.String,java.lang.String)] on the exchange: Exchange[ID-thirumurthi-HP-1615077478318-0-1]
通过一点点挖掘,我注意到当使用多个参数调用接口时客户端无法转换。下面是客户端日志
TIME STARTED : ======> 2021-03-06T22:14:12.142636200
22:14| INFO | CamelLogger.java 158 | client side log :ID-thirumurthi-HP-1615097652037-0-2 == Renton
... the result updating address : Renton
22:14| INFO | CamelLogger.java 158 | client side log :ID-thirumurthi-HP-1615097652037-0-4 == [Ljava.lang.Object;@6f70a21b
... the result updating address zip both : [Ljava.lang.Object;@6f70a21b
我有几个问题:
-
在客户端,我在类 UpdateDeliveryDetailsFromClient.java 中自动连接了 DeliveryService 接口,但由于 bean 在
<camel:proxy..
内,spring 无法解析它。有什么办法可以使用@Autowired注解在这里注入bean吗? -
当调用方法有不同的方法签名时,为什么Camel在这里无法识别正确的bean方法? (我可以尝试其他选项,例如在 Camel 标头中指定方法名称或直接调用方法。)
注意:当我在界面中尝试使用一种方法时,流程有效。
详细的日志异常在底部。
服务器项目代码
package com.springremote.srvr;
public interface DeliveryService {
String updateDelivery(String address);
String updateDelivery(String address,String zipCode);
}
package com.springremote.srvr;
import org.apache.camel.Handler;
public class DeliveryServiceImpl implements DeliveryService{
@Override
public String updateDelivery(String address) {
return "<< SERVER >> : Delivery Info updated with address ONLY : "+address;
}
@Override
public String updateDelivery(String address,String zipCode) {
return "<< SERVER>> :Delivery Info updated with address & zip :"+address +" & " + zipCode;
}
}
- Spring DSL 上下文 xml (file:context-springremote-server.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:broker="http://activemq.apache.org/schema/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://camel.apache.org/schema/spring
http://camel.apache.org/schema/spring/camel-spring.xsd
http://activemq.apache.org/schema/core
http://activemq.apache.org/schema/core/activemq-core.xsd">
<import resource="activemq-broker.xml" />
<bean id="deliveryService" class="com.springremote.srvr.DeliveryServiceImpl" />
<!-- Don't use org.apache.activemq.camel.component.ActiveMQComponent since this is part of older activemq-camel dependency and doesn't working with camel 3.0+ -->
<bean id="activemq" class="org.apache.camel.component.activemq.ActiveMQComponent">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="activemq:queue:example" />
<log message="serverside log => ${header.camelFileName} = ${body}" />
<to uri="bean:deliveryService" />
</route>
</camelContext>
</beans>
activemq-borker.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:broker="http://activemq.apache.org/schema/core"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd">
<!-- setup a real ActiveMQ broker which listen on port 61616 -->
<broker:broker useJmx="false" persistent="false" brokerName="mybroker">
<broker:transportConnectors>
<broker:transportConnector name="tcp" uri="tcp://localhost:61616"/>
</broker:transportConnectors>
</broker:broker>
</beans>
package com.springremote.srvr;
import org.apache.camel.main.Main;
import org.apache.camel.spring.SpringCamelContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
public class DeliveryServiceServerUsingCamel3Main {
public static void main(String[] args) {
Main mainapp= new Main();
ApplicationContext context = new ClasspathXmlApplicationContext(
"context-springremote-server.xml");
SpringCamelContext camelContext = (SpringCamelContext)context.getBean("camel");
mainapp.addConfiguration(camelContext);
try {
mainapp.run();
} catch (Exception e) {
e.printstacktrace();
}
}
}
客户端代码
package com.remote.client;
public interface DeliveryService {
String updateDelivery(String address);
String updateDelivery(String address,String zipCode);
}
package com.remote.client;
import org.springframework.beans.factory.annotation.Autowired;
public class UpdateDeliveryDetailsFromClient {
// Didn't include the getter setter method here.
DeliveryService deliveryService;
public String updateDelivery(String updateInfo) {
return this.getDeliveryService().updateDelivery(updateInfo);
}
public String updateDelivery(String address,String zipCode) {
return this.getDeliveryService().updateDelivery(address,zipCode);
}
}
- 上下文文件名 delivery-service-client-remote-context.xml
<!-- <beans tag not included,it is mostly the same as in the server side context.xml-->
<bean id="activemq" class="org.apache.camel.component.activemq.ActiveMQComponent">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
<camel:proxy id="deliveryService" serviceInterface="com.remote.client.DeliveryService" serviceUrl="direct:input"/>
<bean id="deliveryInfo" class="com.remote.client.UpdateDeliveryDetailsFromClient">
<property name="deliveryService" ref="deliveryService" />
</bean>
<camelContext id="camel" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct:input" />
<log message="client side log : ${body}"/>
<to uri="activemq:queue:example" />
</route>
</camelContext>
</beans>
package com.remote.client;
import java.time.LocalDateTime;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.impl.engine.DefaultProducerTemplate;
import org.apache.camel.spring.SpringCamelContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClasspathXmlApplicationContext;
public class DeliveryServiceClientMainSeperateVM {
public static void main(String[] args) throws Exception{
ApplicationContext appContext = new ClasspathXmlApplicationContext("delivery-service-client-remote-context.xml");
SpringCamelContext camelContext = (SpringCamelContext)appContext.getBean("camel");
try {
System.out.println("STARTED @ : ======> "+LocalDateTime.Now());
camelContext.start();
UpdateDeliveryDetailsFromClient shipmentReceiver = camelContext.getRegistry().lookupByNameAndType("deliveryInfo",UpdateDeliveryDetailsFromClient.class);
String updateStatus = shipmentReceiver.updateDelivery("Renton");
System.out.println("... the result updating address : " + updateStatus);
updateStatus = shipmentReceiver.updateDelivery("Renton","98055");
System.out.println("... the result updating address zip both : " + updateStatus);
Thread.sleep(15000);
System.out.println("STOPPED @ : ========> "+LocalDateTime.Now());
} finally {
camelContext.stop();
}
}
}
日志详情:
org.apache.camel.component.bean.AmbiguousMethodCallException: Ambiguous method invocations possible: [public java.lang.String com.springremote.srvr.DeliveryServiceImpl.updateDelivery(java.lang.String),java.lang.String)] on the exchange: Exchange[ID-thirumurthi-HP-1615077478318-0-1]
at org.apache.camel.component.bean.BeanInfo.chooseBestPossibleMethodInfo(BeanInfo.java:871)
at org.apache.camel.component.bean.BeanInfo.chooseMethodWithMatchingBody(BeanInfo.java:800)
at org.apache.camel.component.bean.BeanInfo.chooseMethod(BeanInfo.java:634)
at org.apache.camel.component.bean.BeanInfo.createInvocation(BeanInfo.java:286)
at org.apache.camel.component.bean.BeanInfo.createInvocation(BeanInfo.java:186)
at org.apache.camel.component.bean.AbstractBeanProcessor.process(AbstractBeanProcessor.java:129)
at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:55)
at org.apache.camel.component.bean.BeanProducer.process(BeanProducer.java:41)
at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:134)
at org.apache.camel.processor.errorhandler.RedeliveryErrorHandler$RedeliveryState.run(RedeliveryErrorHandler.java:476)
at org.apache.camel.impl.engine.DefaultReactiveExecutor$Worker.schedule(DefaultReactiveExecutor.java:185)
at org.apache.camel.impl.engine.DefaultReactiveExecutor.scheduleMain(DefaultReactiveExecutor.java:59)
at org.apache.camel.processor.Pipeline.process(Pipeline.java:87)
at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:228)
at org.apache.camel.impl.engine.DefaultAsyncProcessorAwaitManager.process(DefaultAsyncProcessorAwaitManager.java:78)
at org.apache.camel.support.AsyncProcessorSupport.process(AsyncProcessorSupport.java:40)
at org.apache.camel.component.jms.EndpointMessageListener.onMessage(EndpointMessageListener.java:129)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:736)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:696)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:674)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:318)
at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:257)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncmessageListenerInvoker.invokeListener
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)