11.11. Service Activator
概述
服务激活器 模式(如 图 11.9 “服务激活器模式” 所示)描述了调用服务操作以响应传入请求消息的情况。服务激活器标识要调用的操作,并提取要用作操作参数的数据。最后,服务激活器使用从消息中提取的数据调用操作。操作调用可以是单向(仅限请求)或双向(request/reply)。
图 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; } } }
其中 message data to method 参数的绑定由 @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
, identifes this 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>
Exchange 实例作为 Velocity 变量 交换
提供,它可让您使用 ${exchange.getProperty ("
检索 userid Exchange 属性。当前 In 消息的正文 userid
")}${body}
包含 getUserAccBalance ()
方法调用的结果。