是否可以使用 java 接口或 bean 启动骆驼路线?
Posted
技术标签:
【中文标题】是否可以使用 java 接口或 bean 启动骆驼路线?【英文标题】:Is it possible to kick off a camel route using a java interface or bean? 【发布时间】:2011-03-22 22:01:13 【问题描述】:我想设置一个 spring bean(通过接口或 bean 类)。我可以调用它来“开始”一条路线。
在这个简单的示例中,当我从代码中调用 sayHello("world") 时,我希望它将 sayHello 方法的返回值路由到将其写入文件的端点。
有谁知道这是否可行,或者如何解决? 我知道我可以通过 CXF 公开相同的接口并使其工作,但我真的只想调用一个方法,而不是通过发送 jms 消息或调用 web 服务的麻烦。
public interface Hello
public String sayHello(String value);
from("bean:helloBean").to("file:/data/outbox?fileName=hello.txt");
【问题讨论】:
【参考方案1】:是的,您可以在 Camel 中使用代理/远程处理来执行此操作。
然后,当您调用 sayHello(value) 时,值将被路由到所选路由。来自路由的回复是从 sayHello 方法返回的。
查看这些链接 - http://camel.apache.org/spring-remoting.html - http://camel.apache.org/hiding-middleware.html -http://camel.apache.org/using-camelproxy.html
Camel in Action 一书的第 14 章更详细地介绍了这一点: http://www.manning.com/ibsen
【讨论】:
感谢您回答我的问题。我想我需要更新我的 MEAP 书。对于第 14 章,它说 TBD。不过这本书很有帮助!【参考方案2】:我需要查看克劳斯的答案,但为了获得快速而肮脏的 UI,我采用了不同的方法。
我使用的是 Spring MVC 3.1.X,并为我的应用程序中的各种项目提供了一个管理控制台。我编写了一个控制器来显示路由及其状态,并提供了根据需要启动和停止路由的链接。以下是部分代码:
@Controller
public class CamelController
private static final Log LOG = LogFactory.getLog(CamelController.class);
@Autowired
@Qualifier("myCamelContextID")
private CamelContext camelContext;
@RequestMapping(value = "/dashboard", method = RequestMethod.GET)
public String dashboard(Model model)
if (LOG.isDebugEnabled())
LOG.debug("camel context is suspended : " + camelContext.isSuspended());
List<Route> routes = camelContext.getRoutes();
List<RouteStatus> routeStatuses = new ArrayList<RouteStatus>();
for (Route r : routes)
RouteStatus rs = new RouteStatus();
rs.setId(r.getId());
rs.setServiceStatus(camelContext.getRouteStatus(r.getId()));
routeStatuses.add(rs);
model.addAttribute("routeStatuses", routeStatuses);
return "dashboard";
@RequestMapping(value = "/dashboard/routeId/start", method = RequestMethod.GET)
public String startRoute(@PathVariable String routeId)
try
camelContext.startRoute(routeId);
if (LOG.isDebugEnabled())
LOG.debug("camel context is starting route [" + routeId + "]");
catch (Exception e)
LOG.error("failed to start camel context [" + camelContext + "]");
return "redirect:/dashboard";
@RequestMapping(value = "/dashboard/routeId/stop", method = RequestMethod.GET)
public String stopRoute(@PathVariable String routeId)
try
camelContext.stopRoute(routeId);
if (LOG.isDebugEnabled())
LOG.debug("camel context is stopping route [" + routeId + "]");
catch (Exception e)
LOG.error("failed to stop camel context [" + camelContext + "]");
return "redirect:/dashboard";
我做了一个小 POJO 来配合它:
public class RouteStatus
private String id;
private ServiceStatus serviceStatus;
public String getId()
return id;
public void setId(String id)
this.id = id;
public ServiceStatus getServiceStatus()
return serviceStatus;
public void setServiceStatus(ServiceStatus serviceStatus)
this.serviceStatus = serviceStatus;
【讨论】:
【参考方案3】:你可以使用ProducerTemplate:
import org.apache.camel.Produce;
import org.apache.camel.ProducerTemplate;
import org.springframework.stereotype.Component;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
@Component
public class HelloImpl implements Hello
@Produce(uri = "direct:start")
private ProducerTemplate template;
@Override
public Object sayHello(String value) throws ExecutionException, InterruptedException
Future future = template.asyncSendBody(template.getDefaultEndpoint(), value);
return future.get();
你的骆驼路线应该是这样的:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.mycompany.camel"/>
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct:start"/>
<to uri="log:com.mycompany.camel?level=DEBUG"/>
</route>
</camelContext>
</beans>
【讨论】:
【参考方案4】:因为我的路线是使用CamelConfiguration 的弹簧组件。为了在骆驼路线中使用我的界面,我做了以下操作。
@Component
public class SomeRoute extends RouteBuilder
@Autowired
private ApplicationContext applicationContext;
@Override
public void configure() throws Exception
from("direct:someroute")
.bean(applicationContext.getBean(SomeInterface.class).getClass(), "someAbstractMethod")
.to("direct:otherroute");
这是非常直接的情况,如果您有多个使用相同接口或抽象类的 bean,您可能需要在对 bean 使用 .getClass()
之前执行一些逻辑。
【讨论】:
【参考方案5】:其他答案都不适合我,它们都已构建并且有效,但路由没有触发。
这是我最终使用的解决方案:
import org.apache.camel.Handler;
public class Hello
@Produce(uri = "direct:start")
private ProducerTemplate producer;
@Handler
public void sayHello()
producer.sendBody("hello")
from("timer:hubspotContacts?repeatCount=1").bean(Hello.class);
from("direct:start").to("log:hello");
第一条路线中的timer 组件是我缺少的关键部分。使用repeatCount=1
,它只会在启动时触发一次,并导致调用 bean 方法。如果您需要多次调用该方法,它还支持调用速率或延迟。
@Handler
注释用作标记,因此方法名称不必在路由配置中明确说明
direct 组件将生产者与其消费者连接起来
【讨论】:
以上是关于是否可以使用 java 接口或 bean 启动骆驼路线?的主要内容,如果未能解决你的问题,请参考以下文章
Spring BootSpring Boot之使用ImportBeanDefinitionRegistrar类实现动态注册Bean