我正在尝试在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;
}
}
答案 0 :(得分:4)
您的原始要求可以通过以下步骤来实现。
创建自定义绑定界面(您也可以使用默认的@EnableBinding(Source.class)
)
public interface CustomSource {
String OUTPUT = "customoutput";
@Output(CustomSource.OUTPUT)
MessageChannel output();
}
注入绑定频道
@Component
@EnableBinding(CustomSource.class)
public class CustomOutputEventSource {
@Autowired
private CustomSource customSource;
public void sendMessage(String message) {
customSource.output().send(MessageBuilder.withPayload(message).build());
}
}
测试
@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());
}
}