1.stream 配置中的含义
当我们使用默认group,和destination时默认创建名为input 的持久化的topic类型的exchange。
队列是一个destination前缀然后一个随你名称的自动删除队列。
现在我们自定义group,destination。如下。
spring.cloud.stream.bindings.input.group=queueName spring.cloud.stream.bindings.input.destination=exchangeName
根据destination,帮我们创建了一个持久化的topic类型的exchange。
根据group,帮我们创建了一个持久化的queue。
总结:对于RabbitMQ,destination 对应的是exchange,group对应的是queue(带有前缀)。对于kafka,destination 对应的是Topic,group就是对应的消费group。对于一个应用集群,如果不需要重复消费消息,必须定义group,否则不必定义group(比如刷新配置消息)。
2.发送消息
1.定义通道,通道名为mqScoreOutput
spring.cloud.stream.bindings.mqScoreOutput.destination=exchangeName22.定义接口
public interface SendChannel { String SCORE_OUPUT = "mqScoreOutput"; @Output(SendChannel.SCORE_OUPUT) MessageChannel scoreOutput(); }3.进行绑定
@EnableBinding(SendChannel.class) public class SendServerConfig { }4.注入可以发送消息的bean
@Service public class SendServer { @Autowired private SendChannel sendChannel; @Autowired private MessageChannel mqScoreOutput; public void send1() { Message<String> fffff = MessageBuilder.withPayload("fffffsend1").build(); sendChannel.scoreOutput().send(fffff); System.out.println("发送消息send1"); } public void send2() { Message<String> fffff = MessageBuilder.withPayload("fffffsend2").build(); mqScoreOutput.send(fffff); System.out.println("发送消息send2"); } }
3.接收消息
1.定义通道
spring.cloud.stream.bindings.mqScoreInput.group=queueName2 spring.cloud.stream.bindings.mqScoreInput.destination=exchangeName22.定义接口
public interface ReceiverChannel { String SCORE_INPUT = "mqScoreInput"; @Input(ReceiverChannel.SCORE_INPUT) SubscribableChannel scoreInput(); }3.进行绑定
@EnableBinding({ReceiverChannel.class}) public class ReceiverServerConfig { @StreamListener(ReceiverChannel.SCORE_INPUT) public void receive(Object object) { System.out.println(object); } }
4.注意事项
接收消息通道和发送消息通道名不可以重复。即使destination一样。例如:
spring.cloud.stream.bindings.mqScoreInput.group=queueName2 spring.cloud.stream.bindings.mqScoreInput.destination=exchangeName2 spring.cloud.stream.bindings.mqScoreOutput.destination=exchangeName2我们不用mqScoreOutput 这个通道名,发送消息的时候也用mqScoreInput.
public interface SendChannel { String SCORE_OUPUT = "mqScoreInput"; @Output(SendChannel.SCORE_OUPUT) @Qualifier("mqScoreOutput") MessageChannel scoreOutput(); }
接收消息的时候报如下错误。
Caused by: org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers
5.Spring Integration 原生支持接收消息
1.定义通道
spring.cloud.stream.bindings.mq1.group=queueName spring.cloud.stream.bindings.mq1.destination=exchangeName2.定义接口
public interface ReceiverChannel2 { String INPUT = "mq1"; @Input(INPUT) SubscribableChannel input(); }3.进行绑定
@EnableBinding({ReceiverChannel2.class}) public class ReceiverServerConfig2 { @ServiceActivator(inputChannel = ReceiverChannel2.INPUT) public void receive(Object object) { System.out.println(object); } }
6.消息转换
1.配置contentType类型
spring.cloud.stream.bindings.mqScoreInput.group=queueName2 spring.cloud.stream.bindings.mqScoreInput.destination=exchangeName2 spring.cloud.stream.bindings.mqScoreInput.contentType=application/json spring.cloud.stream.bindings.mqScoreOutput.destination=exchangeName2 spring.cloud.stream.bindings.mqScoreOutput.contentType=application/json2.发送对象
@Service public class SendServer { @Autowired private SendChannel sendChannel; @Autowired @Qualifier("mqScoreOutput") private MessageChannel mqScoreOutput; public void send1() { User u = new User(); u.setId(1L); u.setName("fffffsend1"); Message<User> fffff = MessageBuilder.withPayload(u).build(); sendChannel.scoreOutput().send(fffff); System.out.println("发送消息send1"); } public void send2() { User u = new User(); u.setId(2L); u.setName("fffffsend2"); Message<User> fffff = MessageBuilder.withPayload(u).build(); mqScoreOutput.send(fffff); System.out.println("发送消息send2"); } }3.接收对象
@EnableBinding({ReceiverChannel.class}) public class ReceiverServerConfig { @StreamListener(ReceiverChannel.SCORE_INPUT) public void receive(User user) { System.out.println(user); } }
7.消息反馈
@EnableBinding({ReceiverChannel.class}) public class ReceiverServerConfig { @StreamListener(ReceiverChannel.SCORE_INPUT) @SendTo(SendServer2.SendChannel2.OUTPUT) public Object receive(User user) { user.setId(5555L); return user; } }使用SendTo 指定通道即可。