9.2.4 路由

基于某些路由标准的路由器允许在集成流中进行分支,将消息定向到不同的通道。

例如,假设有一个名为 numberChannel 的通道,整数值通过它流动。假设希望将所有偶数消息定向到一个名为 evenChannel 的通道,而将奇数消息定向到一个名为 oddChannel 的通道。要在集成流中创建这样的路由,可以声明一个 AbstractMessageRouter 类型的 bean,并使用 @Router 注解该 bean:

  1. @Bean
  2. @Router(inputChannel="numberChannel")
  3. public AbstractMessageRouter evenOddRouter() {
  4. return new AbstractMessageRouter() {
  5. @Override
  6. protected Collection<MessageChannel>
  7. determineTargetChannels(Message<?> message) {
  8. Integer number = (Integer) message.getPayload();
  9. if (number % 2 == 0) {
  10. return Collections.singleton(evenChannel());
  11. }
  12. return Collections.singleton(oddChannel());
  13. }
  14. };
  15. }
  16. @Bean
  17. public MessageChannel evenChannel() {
  18. return new DirectChannel();
  19. }
  20. @Bean
  21. public MessageChannel oddChannel() {
  22. return new DirectChannel();
  23. }

这里声明的 AbstractMessageRouter bean 接受来自名为 numberChannel 的输入通道的消息。定义为匿名内部类的实现检查消息有效负载,如果它是偶数,则返回名为 evenChannel 的通道(在路由器 bean 之后声明为 bean)。否则,通道有效载荷中的数字必须为奇数;在这种情况下,将返回名为 oddChannel 的通道(也在 bean 声明方法中声明)。

在 Java DSL 形式中,路由器是通过在流定义过程中调用 route() 来声明的,如下所示:

  1. @Bean
  2. public IntegrationFlow numberRoutingFlow(AtomicInteger source) {
  3. return IntegrationFlows
  4. ...
  5. .<Integer, String>route(n -> n%2==0 ? "EVEN":"ODD", mapping ->
  6. mapping.subFlowMapping("EVEN", sf ->
  7. sf.<Integer, Integer>transform(n -> n * 10).handle((i,h) -> { ... }))
  8. .subFlowMapping("ODD", sf ->
  9. sf.transform(RomanNumbers::toRoman).handle((i,h) -> { ... }))
  10. )
  11. .get();
  12. }

虽然仍然可以声明 AbstractMessageRouter 并将其传递给 route(),但是本例使用 lambda 表达式来确定消息有效负载是奇数还是偶数。

如果是偶数,则返回一个偶数的字符串值。如果是奇数,则返回奇数。然后使用这些值来确定哪个子映射将处理消息。