11.11. 服务激活器
概述
服务 activator 模式(如 图 11.9 “服务激活器模式” 所示)描述了在响应传入请求消息时调用服务操作的情况。服务 activator 标识要调用的操作,并提取要用作操作参数的数据。最后,服务激活器使用从消息中提取的数据调用操作。操作调用可以是单向(仅限请求)或双向(请求/回复)。
图 11.9. 服务激活器模式
在很多方面,服务激活器类似于传统的远程过程调用(RPC),其中操作调用被编码为消息。主要区别在于,服务激活器需要更灵活。RPC 框架标准化请求和回复消息编码(例如,Web 服务操作被编码为 SOAP 消息),而服务活动器通常还需要降低消息传递系统与服务操作之间的映射。
Bean 集成
Apache Camel 为支持服务激活器模式提供的主要机制是 bean 集成。Bean 集成 提供了一个常规框架,用于将传入的消息映射到 Java 对象上方法调用。例如,Java fluent DSL 提供处理器 bean ()
和 beanRef ()
,您可以插入到路由中,以在注册的 Java bean 上调用方法。消息数据到 Java 方法参数的详细映射由 bean 绑定 决定,这可以通过添加注释到 bean 类来实现。
例如,请考虑以下路由,调用 Java 方法 bank Bean.getUserAccBalance ()
,以服务在 JMS/ActiveMQ 队列中传入的请求:
from("activemq:BalanceQueries") .setProperty("userid", xpath("/Account/BalanceQuery/UserID").stringResult()) .beanRef("bankBean", "getUserAccBalance") .to("velocity:file:src/scripts/acc_balance.vm") .to("activemq:BalanceResults");
从 ActiveMQ 端点 activemq:BalanceQueries
中提取的消息具有简单的 XML 格式,提供银行帐户的用户 ID。例如:
<?xml version='1.0' encoding='UTF-8'?> <Account> <BalanceQuery> <UserID>James.Strachan</UserID> </BalanceQuery> </Account>
路由 setProperty ()
中的第一个处理器从 In 消息中提取用户 ID,并将其存储在 userid
Exchange 属性中。最好将其存储在标头中,因为调用 bean 后 In 标头不可用。
服务激活步骤由 beanRef ()
处理器执行,它将传入消息绑定到由 bankBean
bean ID 标识的 Java 对象的 getUserAccBalance ()
方法。以下代码显示了 bank Bean
类的实施示例:
package tutorial; import org.apache.camel.language.XPath; public class BankBean { public int getUserAccBalance(@XPath("/Account/BalanceQuery/UserID") String user) { if (user.equals("James.Strachan")) { return 1200; } else { return 0; } } }
其中,消息数据绑定到方法参数的绑定由 @XPath
注释启用,它会将 UserID
XML 元素的内容注入到 user
method 参数中。在完成调用后,返回值将插入到 Out 消息的正文中,然后复制到路由中下一步的 In 消息中。要让 bean 可以被 beanRef ()
处理器访问,您必须在 Spring XML 中实例化实例。例如,您可以在 META-INF/spring/camel-context.xml
配置文件中添加以下行,以实例化 bean:
<?xml version="1.0" encoding="UTF-8"?> <beans ... > ... <bean id="bankBean" class="tutorial.BankBean"/> </beans>
其中 bean ID, bankBean
, 在注册表中标识此 bean 实例。
bean 调用的输出注入 Velocity 模板,以生成正确格式化的结果消息。Velocity 端点 velocity:file:src/scripts/acc_balance.vm
,使用以下内容指定 velocity 脚本的位置:
<?xml version='1.0' encoding='UTF-8'?> <Account> <BalanceResult> <UserID>${exchange.getProperty("userid")}</UserID> <Balance>${body}</Balance> </BalanceResult> </Account>
交换实例作为 Velocity 变量 Exchange 提供,它可让您使用 ${
属性。当前 In 消息( exchange
.getProperty (" userid
")} 来检索 userid Exchange${body}
)的正文包含 getUserAccBalance ()
方法调用的结果。