11.11. service Activator
概述
服务激活 模式(如 图 11.9 “Service Activator Pattern” 所示)描述了在响应传入请求消息时调用服务操作的情况。服务激活器标识要调用哪些操作,并提取要用作操作参数的数据。最后,服务激活器使用从消息中提取的数据调用操作。操作调用可以是单向(仅请求)或双向(请求/请求)。
图 11.9. Service Activator Pattern
在很多方面,服务激活器类似于传统的远程过程调用(RPC),其中操作调用被编码为消息。主要区别在于,服务激活器需要更灵活。RPC 框架标准化请求和回复消息编码(例如,Web 服务操作编码为 SOAP 消息),而服务激活器通常需要增强消息传递系统与服务操作之间的映射。
Bean 集成
Apache Camel 提供的用于支持服务激活模式的主要机制是 的集成。Bean 集成 提供了一个通用框架,用于将传入消息映射到 Java 对象上方法调用。例如,Java fluent DSL 提供处理器 bean ()
和 beanRef ()
,您可以插入到路由上,以在注册的 Java bean 上调用方法。消息数据到 Java 方法参数的详细映射由 bean 绑定 决定,该绑定可通过向 bean 类添加注解来实施。
例如,请考虑以下路由,该路由调用 Java 方法 BankBean.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 ()
方法。以下代码显示了 BankBean
类的实施示例:
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; } } }
将消息数据绑定到 method 参数的绑定由 @XPath
注释启用,它会将 UserID
XML 元素的内容注入 user
method 参数。在完成调用时,返回值将插入到 Out 消息的正文中,然后复制到路由中下一步的 In 消息中。为了让 beanan 可以被 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 message exchange
.getProperty (" userid
")} 检索 userid Exchange${body}
的正文包含 getUserAccBalance ()
方法调用的结果。