官方对Spring Cloud Stream(简称SCS)的定义是:一个为与消息中间件连接的微服务构建事件驱动的框架。
SCS在Spring Integration项目的基础上在进行了一些封装,并提出一些新的概念,让开发者能够更简单地使用这套消息编程模型。
理解Binder和Binding
-
Binder
用于绑定一个对象(app interface
)到一个逻辑名字(logical name
)上。- 名字用来识别消息的消费者或生产者。
- 被绑定的对象可以是一个队列、一个
ChannelAdapter
、一个MessageChannel
或者一个Spring Bean
。
public interface Binder<T, C extends ConsumerProperties, P extends ProducerProperties> {
Binding<T> bindConsumer(String name, String group, T inboundBindTarget,
C consumerProperties);
Binding<T> bindProducer(String name, T outboundBindTarget, P producerProperties);
}
Binder
接口对外暴露两个方法,分别是bindConsumer
和bindProducer
。
-
Binding
是应用与消息中间件之间的桥梁,由Binder构造。-
Producer Binding(Out Binding)
:应用发出的消息(output)和消费中间件之间的桥梁。 -
Consumer Binding(Input Binding)
:消息中间件和应用对消息处理(iutput)之间的桥梁。
-
消息的发送
source.output().send(MessageBuilder
.withPayload("custompayload")
.setHeader("k1", "v1")
.build());
- 发送的是
Spring Message
,为何到Kafka
、RabbitMQ
或RocketMQ
中却变成了这些消息中间件的消息模型? - 发送到
MessageChannel
中的消息,存储到MessageChannel
也表示储存到内存中。为何最终变成了存储到消息中间件中?
这两个行为会在
Producer Binding
中完成。
-
首先会通过
SendingHandler
这个MessageHandler
去订阅消息发送的MessageChannel
; -
SendingHandler
内部会根据配置信息决定是否使用固定的消息头对消息体进行修改; -
然后把处理完的消息委托给
Binder
构造的MessageHandler
继续处理。- 把
Spring Message
转换成对应MQ的Message Model
- 转换后的
Message Model
发送到MQ broker
中
- 把
Binder
是一个接口,不同实现类会构造不一样的MessageHandler
。KafkaBinder
构造KafkaProducerMessageHandler
;RabbitMQ Binder
构造AmqpOutboundEndpoint
;RocketMQ Binder
构造RocketMQMessageHandler
。
消息的接收
@StreamListener(Sink.INPUT)
public String receive(String msg){
return msg.toUpperCase();
}
- 订阅的明明是消息中间件
Message Model
,为何收到的只是一个String
? - 消息中间件的订阅方式不一样,为何这里可以统一用
@StreamListener
进行订阅?
这两个行为在
Consumer Binding
中完成。
-
首先会根据
Binder
得到ChannelAdapter
;不同的
Binder
构造不一样的ChannelAdapter
,比如Kafka Binder
构造KafkaMessageDrivenChannelAdapter
;RabbitMQ Binder
构造AmqpInboundChannelAdapter
;RocketMQ Binder
构造RocketMQInboundChannelAdapter
。 -
利用
ChannelAdapter
读取消息中间件上的消息,再把这些消息转换成Spring Message
; -
最后发送到
MessageChannel
中; -
之后通过
@StreamListener
注解读取这个MessageChannel
上的消息。
@StreamListener
注解底层实际上是构造了一个MessageHandler
,用MessageHandler
去订阅MessageChannel
上的注解。 同样,其他像@ServiceActivator
、@Transformer
、@Filter
等注解底层也会构造MessageHandler
,去订阅MessageChannel
上的消息。