11.11. Service Activator

概述

service activator 模式在 图 11.9 “Service Activator Pattern” 中显示的是,描述在响应传入请求信息时调用该服务的操作的情况。服务激活器标识要调用哪些操作并提取要用作操作参数的数据。最后,服务激活程序利用从消息中提取的数据来调用操作。操作调用可以是单向(请求)或双向(request/reply)。

图 11.9. Service Activator Pattern

serviceivator 模式

在很多方面,服务激活程序类似于传统的远程过程调用(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>

路由中的第一个处理器 设置Property(),从 In 消息中提取用户 ID,并将其存储在 userid Exchange 属性中。这最好将其存储在标头中,因为调用 bean 后无法使用 In 标头。

服务激活步骤由 beanRef() 处理器执行,它会将传入的消息绑定到由 银行 Bean 识别的 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;
        }
      }
}

如果 @XPath 注释启用消息数据到方法参数的绑定,它会将 UserID XML 元素的内容注入到 用户 方法参数中。在完成调用时,返回值将插入到 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>

在 registry 中,bean ID、tailBean 标识了此 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 ")} 获取 userid Exchange 属性。当前 In 消息的正文 ${body} 中包含 getUserAccBalance() 方法调用的结果。