我正在使用 Camel 4.0.0-RC2 并遵循 有关将 beans 绑定到 RouteTemplate 的文档。我有一个简单的路线模板,可以从可配置的
fromEndpointUri
中使用,并将可配置的 foo
传递给我的 fooConsumer
:
routeTemplate("myTemplate")
// Define the parameters for the route template.
.templateParameter ("fromEndpointUri")
.templateBean ("foo", Foo.class)
// Define the route.
.from ("{{fromEndpointUri}}")
.bean (fooConsumer, "processFoo(${body}, #{{foo}})");
我使用模板创建的路线很简单:
templatedRoute("myTemplate")
.routeId ("myTemplateRoute")
.parameter ("fromEndpointUri", "direct:test")
.bean ("foo", Foo.class, ignored -> new Foo());
通过此路由发送消息时,会抛出错误
No type converter available to convert from type: java.lang.String to the required type: com.example.Foo
。相关的堆栈跟踪是:
org.apache.camel.NoTypeConversionAvailableException: No type converter available to convert from type: java.lang.String to the required type: com.example.Foo
at org.apache.camel.impl.converter.CoreTypeConverterRegistry.mandatoryConvertTo(CoreTypeConverterRegistry.java:279) ~[camel-base-4.0.0-RC2.jar:4.0.0-RC2]
at org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluateParameterValue(MethodInfo.java:717) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
... 94 more
Wrapped by: org.apache.camel.component.bean.ParameterBindingException: Error during parameter binding on method: public java.util.List com.example.FooConsumer.processFoo(java.lang.String,com.example.Foo) at parameter #1 with type: class com.example.Foo with value type: class java.lang.String and value: #foo-1
at org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluateParameterValue(MethodInfo.java:728) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
at org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluateParameterExpressions(MethodInfo.java:618) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
at org.apache.camel.component.bean.MethodInfo$ParameterExpression.evaluate(MethodInfo.java:591) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
at org.apache.camel.component.bean.MethodInfo.initializeArguments(MethodInfo.java:262) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
at org.apache.camel.component.bean.MethodInfo.createMethodInvocation(MethodInfo.java:270) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
at org.apache.camel.component.bean.BeanInfo.createInvocation(BeanInfo.java:266) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
at org.apache.camel.component.bean.AbstractBeanProcessor.process(AbstractBeanProcessor.java:128) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
at org.apache.camel.component.bean.BeanProcessor.process(BeanProcessor.java:81) ~[camel-bean-4.0.0-RC2.jar:4.0.0-RC2]
...
如何将路线的
Foo
实例传递给我的 FooConsumer
?我尝试过的一些变化是:
变化 | 错误 |
---|---|
|
|
|
|
|
|
|
|
|
|
当然可以这样做,因为示例显示使用
myClient
语法将 aws2-s3
bean 传递到 #{{myClient}}
端点。
我找到了一种使用这些路线模板的方法,就像我在这里尝试的那样,但感觉不太干净。也许我正在尝试以它们不应该使用的方式使用它们。不管怎样,为了让它工作,我在定义路由模板的类中创建了一个内部
ServiceActivator
类:
private class ServiceActivator {
private final Foo foo;
public ServiceActivator(final RouteTemplateContext routeTemplateContext) {
this.foo = (
routeTemplateContext
.getLocalBeanRepository ()
.lookupByNameAndType ("foo", Foo.class)
);
}
@Handler
public void processFoo(@Body final String body) {
// do something
}
}
然后,我将路线模板更新为:
foo
的声明,因为拥有该定义会使 Camel 尝试为其创建默认值。ServiceActivator
。ServiceActivator
中的bean
。routeTemplate("myTemplate")
// Define the parameters for the route template
.templateParameter ("fromEndpointUri")
.templateBean ("serviceActivator, ServiceActivator.class, ServiceActivator::new)
// Define the route.
.from("{{fromEndpointUri}}")
.bean("{{serviceActivator}}")
并将我的模板路线保留为:
templatedRoute("myTemplate")
.routeId ("myTemplateRoute")
.parameter ("fromEndpointUri", "direct:test")
.bean ("foo", Foo.class, ignored -> new Foo());
再次,这看起来几乎像是一种 hack,而不是按照 Camel 的预期用途来使用该功能。从我单步执行代码来看,路由模板参数和 bean 仅在创建路由时可用,因此这是在路由创建期间捕获所有信息的一种方法,以便在以后执行路由时使用。