Apache Camel - CamelContext
CamelContext 提供了对Camel中所有其他服务的访问,如下图所示 −
让我们看看各种服务。 默认情况下,Registry 模块是一个 JNDI 注册表,它保存应用程序使用的各种 Javabean 的名称。 如果您将 Camel 与 Spring 一起使用,这将是 Spring ApplicationContext。如果您在 OSGI 容器中使用 Camel,则这将是 OSGI registry。 顾名思义,Type converters(类型转换器)包含各种加载的类型转换器,它们将您的输入从一种格式转换为另一种格式。您可以使用内置类型转换器或提供您自己的转换机制。 Components 模块包含您的应用程序使用的组件。 这些组件是通过自动发现在您指定的classpath上加载的。对于 OSGI 容器,只要激活新包,就会加载这些容器。 我们已经在前面的章节中讨论了Endpoints(端点)和Routes(路由)。Data formats(数据格式)模块包含加载的数据格式,最后Languages(语言)模块表示加载的语言。
此处的代码片段将让您了解如何在 Camel 应用程序中创建 CamelContext −
CamelContext context = new DefaultCamelContext(); try { context.addRoutes(new RouteBuilder() { // Configure filters and routes } } );
DefaultCamelContext 类提供了 CamelContext 的具体实现。 在addRoutes方法中,我们创建RouteBuilder的匿名实例。您可以创建多个 RouteBuilder 实例来定义多个路由。 同一上下文中的每个路由必须有唯一的 ID。 可以在运行时动态添加路由。 与之前定义的 ID 相同的路由将替换旧路由。
接下来描述 RouteBuilder 实例内部的内容。
Routes
路由器定义将消息from移动到to位置的规则。 您可以使用 RouteBuilder 在 Java DSL 中定义路由。您可以通过扩展内置 RouteBuilder 类来创建路线。该路线以 from 端点开始,并以一个或多个 to 端点结束。 在两者之间,您实现处理逻辑。 您可以在单个 configure 方法中配置任意数量的路由。
这是一个如何创建路由的典型示例 −
context.addRoutes(new RouteBuilder() { @Override public void configure() throws Exception { from("direct:DistributeOrderDSL") .to("stream:out"); } }
我们重写RouteBuilder类的configure方法并在其中实现我们的路由和过滤机制。 在当前情况下,我们将从端点 DistributeOrderDSL 接收的输入重定向到由端点 stream:out 指定的控制台。
语言选择
您可以用不同的语言创建路线。 以下是如何用三种不同语言定义同一路线的几个示例 −
Java DSL
from ("file:/order").to("jms:orderQueue");
Spring DSL
<route> <from uri = "file:/order"/> <to uri = "jms:orderQueue"/> </route>
Scala DSL
from "file:/order" -> "jms:orderQueue"
过滤器
您使用过滤器来选择输入内容的一部分。 要设置过滤器,您可以使用任意 Predicate 实现。 然后,过滤后的输入将发送到您所需的目标端点。 在此示例中,我们过滤掉肥皂的所有订单,以便将这些订单集中发送给肥皂供应商。
from("direct:DistributeOrderDSL") .split(xpath("//order[@product = 'soaps']/items")) .to("stream:out");
在示例中,我们使用 xpath 谓词进行过滤。 如果您喜欢使用 Java 类进行过滤,请使用以下代码 −
from("direct:DistributeOrderDSL") .filter() .method(new Order(),"filter") .to("stream:out");
Order 是您的自定义 Java 类,具有您自己的过滤机制。
您可以在单个路由中组合多个谓词,如下所示 −
from("direct:DistributeOrderDSL") .choice() .when(header("order").isEqualTo("oil")) .to("direct:oil") .when(header("order").isEqualTo("milk")) .to("direct:milk") .otherwise() .to("direct:d");
因此,现在所有"石油"订单将发送给石油供应商,"牛奶"订单将发送给牛奶供应商,其余订单将发送给公共池。
自定义处理器
您还可以使用自定义处理。 下面的示例创建一个名为 myCustomProcessor 的自定义处理器,并在路由构建器中使用它。
Processor myCustomProcessor = new Processor() { public void process(Exchange exchange) { // implement your custom processing } }; RouteBuilder builder = new RouteBuilder() { public void configure() { from("direct:DistributeOrderDSL") .process(myProcessor); } };
您可以使用自定义处理器以及选择和过滤来更好地控制路由 −
from("direct:DistributeOrderDSL") .filter(header("order").isEqualTo("milk")) .process(myProcessor);
使用 XML
如果您愿意,可以使用更庞大的 XML 来定义路由。 以下 XML 片段展示了如何通过 Spring XML 创建路由以及一些过滤 −
<camelContext xmlns = "http://camel.apache.org/schema/spring"> <route> <from uri = "direct:DistributeOrderXML"/> <log message = "Split by Distribute Order"/> <split> <xpath>//order[@product = 'Oil']/items</xpath> <to uri = "file:src/main/resources/order/"/> <to uri = "stream:out"/> </split> </route> </camelContext>
了解了如何构建路由后,我们现在将了解创建端点的各种技术。