15.3 自定义消息通道
在Spring Cloud 学习笔记 ——Spring Cloud Stream 概念及 HelloWorld中使用了默认的 Sink 通道,也可以自定义消息通道
- 1.创建一个自定义消息通道接口类,起名叫 MyChannel
public interface MyChannel {
String INPUT = "javaboy-input";
String OUTPUT = "javaboy-output";
@Output(OUTPUT)
MessageChannel output();
@Input(INPUT)
SubscribableChannel input();
}
默认的 Sink 通道接口
public interface Sink {
String INPUT = "input";
@Input("input")
SubscribableChannel input();
}
对比自定义和默认提供的,自定义的除了有 input 外,还有 output,因为不仅要接收消息,还要发送消息, output 就是发送消息的。
-
- 创建自定义的消息接收器
@EnableBinding(MyChannel.class)
public class MsgReceiver2 {
private static final Logger logger = LoggerFactory.getLogger(MyChannel.class);
@StreamListener(MyChannel.INPUT)
public void receive(Object payload){
logger.info("received2:" + payload);
}
}
这个消息接收器与之前在Spring Cloud 学习笔记 ——Spring Cloud Stream 概念及 HelloWorld定义的一样。
- 3.定义个 Controller 来做消息发布到队列的测试
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
@Autowired
MyChannel myChannel;
@GetMapping("/hello")
public void hello(){
MessageChannel messageChannel = myChannel.output();
MessageBuilder<String> builder = MessageBuilder.withPayload("hello spring cloud stream!");
Message<String> message = builder.build();
boolean send = messageChannel.send(message);
logger.info("" + send);
}
}
这里类中没有 Spring Cloud Stream jar 中的东西,都是 Spring 的。
- 4.在 application.properties 中配置自定义通道的 input 和 output 的 destination ,使其绑定在一起,而不在之前的文章中在浏览器中直接输入。
spring.cloud.stream.bindings.javaboy-input.destination=javaboy-topic
spring.cloud.stream.bindings.javaboy-output.destination=javaboy-topic
都绑定到 javaboy-topic 的队列中
- 5.访问接口,观察控制台
可以,看到在 HelloController 中操作 output 发送的消息在 MsgReceiver2 中处理了。
观察 RabbitMQ Management 中的信息
-
1.两个 Connections
-
2.进入第一个 Connection
可以看到有 3 个通道
点击第一个通道
可以看到队列名,是一 input 开头的队列,是默认给 Sink 类中定义的 input。
再点击队列
就回到了在Spring Cloud 学习笔记 ——Spring Cloud Stream 概念及 HelloWorld中直接页面发消息的界面 -
2 .点击第一个连接中的第二个通道
可以看到是上文中自定义的 javaboy-topic 通道名。
再点击通道名,一样跳到可以手动在页面发布消息的页面
点击第一个连接中的第三个 Channel
没有任何的 Consumer,而队列是在 Consumer 中,队列也不存在
-
3.进入第二个 Connection
可以看到只有一个通道(Channel)
点击进入通道
没有任何队列
最后看一眼交换机 exchange,很明显能发现项目中 Sink 、MyChannel 定义的内容
-
思考
一共有项目中我们有两个通道,一个是 Sink 类中默认给的通道,一个是我们自定义的 javaboy-topic 通道,虽然在 RabbitMQ 中连接是两个,并且连接有一个到三个不等的 Channel ,Channel 中 有或者没有队列,但是队列真是存在的就两个,队列的名字是在 application 中 input 和 output 的 destination 的值(队列 input 是默认配置的,在 applciation.properties 中看不到)。
自认为 Connection 能关联 Channel,Channel 能关联 Queue。exchange 的作用还不知道,待总结。。。