使用Spring Cloud Stream Source将方法结果发送到流

时间:2016-09-08 16:32:46

标签: java spring-boot spring-cloud-stream

我正在尝试在Spring Boot应用程序中创建一个Spring Cloud Stream Source Bean,它只是将方法的结果发送到流(基础Kafka主题绑定到流)。

我见过的大多数Stream示例使用@InboundChannelAdapter注释使用轮询器将数据发送到流。但我不想使用轮询器。我已经尝试将轮询器设置为空数组,但另一个问题是当使用@InboundChannelAdapter时,您无法获得任何方法参数。

我尝试做的整体概念是从入站流中读取的。执行一些异步处理,然后将结果发布到出站流。所以使用处理器似乎也不是一种选择。我正在使用带有Sink通道的@StreamListener来读取入站流,并且可以正常工作。

以下是我一直在尝试的一些代码,但这根本不起作用。我希望它会如此简单,因为我的沉没,但也许不是。正在寻找某人指向一个不是处理器的源的示例(即不需要在入站通道上监听)并且不使用@InboundChannelAdapter或者给我一些设计技巧来完成什么我需要以不同的方式做。谢谢!

@EnableBinding(Source.class)
public class JobForwarder {

   @ServiceActivator(outputChannel = Source.OUTPUT)
   @SendTo(Source.OUTPUT)
   public String forwardJob(String message) {
       log.info(String.format("Forwarding a job message [%s] to queue [%s]", message, Source.OUTPUT));
       return message;
   }
}

3 个答案:

答案 0 :(得分:4)

您的原始要求可以通过以下步骤来实现。

  1. 创建自定义绑定界面(您也可以使用默认的@EnableBinding(Source.class)

    public interface CustomSource {
        String OUTPUT = "customoutput";
    
        @Output(CustomSource.OUTPUT)
        MessageChannel output();
    }
    
  2. 注入绑定频道

    @Component
    @EnableBinding(CustomSource.class)
    public class CustomOutputEventSource {
    
        @Autowired
        private CustomSource customSource;
    
        public void sendMessage(String message) {
            customSource.output().send(MessageBuilder.withPayload(message).build());
        }
    }
    
  3. 测试

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class CustomOutputEventSourceTest {
    
        @Autowired
        CustomOutputEventSource output;
    
        @Test
        public void sendMessage() {
            output.sendMessage("Test message from JUnit test");
        }
    }
    

答案 1 :(得分:0)

因此,如果您不想使用Poller,是什么原因导致forwardJob()方法被调用?

您不能只调用该方法并期望结果转到输出通道。

使用您当前的配置,您需要在包含入站消息的服务上inputChannel(以及向该频道发送消息的内容)。它不必受运输约束;它可以很简单MessageChannel @Bean

或者,您可以使用@Publisher发布方法调用的结果(以及返回给调用方) - docs here

@Publisher(channel = Source.OUTPUT)

答案 2 :(得分:0)

感谢您的投入。我花了一段时间才回到这个问题。我确实尝试阅读@Publisher的文档。它看起来正是我所需要的,但我无法初始化正确的bean以使其正确连线。

要回答您的问题,在输入的某些异步处理之后调用forwardJob()方法。

最终我只是直接使用spring-kafka库实现,而且更加明确,感觉更容易上手。我认为我们将坚持使用kafka作为唯一的通道绑定,所以我认为我们会坚持使用该库。

然而,我们最终确实让spring-cloud-stream库工作得非常简单。这是没有轮询器的单个源的代码。

@Component
@EnableBinding(Source.class)
public class JobForwarder {

    private Source source;

    @Autowired
    public ScheduledJobForwarder(Source source) {
        this.source = source;
    }

    public void forwardScheduledJob(String message) {
        log.info(String.format("Forwarding a job message [%s] to queue [%s]", message, Source.OUTPUT));
        source.output().send(MessageBuilder.withPayload(message).build());
    }
}