作为消息端点的网关和服务激活器有什么区别(就企业集成模式而言)?
3 回答
服务激活器调用应用程序开发人员提供实现的对象上的方法。Spring Integration 负责使用来自输入通道的消息调用该方法,并将结果分流到某个输出通道。应用程序提供的代码可以做一些任意的工作。
对于网关应用开发者只提供一个接口,它的实现由Spring提供。
Spring Integration 文档的附录包括一个Cafe 示例,其中 Barista 是通过服务激活器调用的服务,Cafe 是网关。
应用程序的 main 方法从 Spring 应用程序上下文中查找一个 Cafe 对象,并在其上调用 placeOrder,将 Order 作为参数传入:
public static void main(String[] args) {
AbstractApplicationContext context = null;
if (args.length > 0) {
context = new FileSystemXmlApplicationContext(args);
}
else {
context = new ClassPathXmlApplicationContext(
"cafeDemo.xml", CafeDemo.class);
}
Cafe cafe = (Cafe) context.getBean("cafe");
for (int i = 1; i <= 100; i++) {
Order order = new Order(i);
order.addItem(DrinkType.LATTE, 2, false);
order.addItem(DrinkType.MOCHA, 3, true);
cafe.placeOrder(order);
}
}
Cafe 是应用程序不为其提供实现的接口。Spring 生成一个实现,将传递给它的订单发送到称为“订单”的输入通道。
在管道的下方,有两个服务激活器引用了 Barista。Barista 是一个 POJO,其代码可用于创建如下所示的饮品:
public Drink prepareHotDrink(OrderItem orderItem) {
try {
Thread.sleep(this.hotDrinkDelay);
System.out.println(Thread.currentThread().getName()
+ " prepared hot drink #" + hotDrinkCounter.incrementAndGet()
+ " for order #" + orderItem.getOrder().getNumber()
+ ": " + orderItem);
return new Drink(orderItem.getOrder().getNumber(),
orderItem.getDrinkType(),
orderItem.isIced(), orderItem.getShots());
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
return null;
}
}
咖啡师从服务激活器的输入通道接收饮料订单,并在其上调用一个返回饮品的方法,该饮品通过服务激活器的输出通道“preparedDrinks”发送。
对我来说,网关用于进行抽象并为一个或多个后端服务提供规范化的 API。例如,您有 5 个提供者使用不同的方式与您交互(SOAP、REST、XML/http 等等),但您的客户只需要一种方式来获取数据(比如说 json/REST)。网关会将来自您的客户端的 json 请求转换为具有自己协议的正确后端,然后将后端响应转换为 json 以将响应提供给您的客户端。
服务激活器更多地充当传入消息的触发器。假设您的激活器轮询数据库以获取传入消息,然后当条件满足“激活”时,它会调用底层服务。