SpringCloudStream看名字就知道他和消息队列相关,但它又不是消息队列,准确来说它类似于硬件里面的驱动程序,也就是前面说的适配器模式的体现。
在系统开发里面难免用到消息队列,但各个的消息队列又有所区别,SpringCloudStream的作用就是屏蔽各种消息队列的区别,对消息队列的API进行进一步的抽象,使得在springcloud里面能更加方便的集成各种消息系统。
首先来看SpringCloudStream的组成:
不管是生产者还是消费者,并不会直接和消息中间件打交道,在SpringCloudStream中抽象了已成binder(绑定层),有了这一层,使用者并不关心具体的消息中间件配置了,由访问层真正的和消息队列进行通信。
代码Git地址:https://gitee.com/hankin_chj/springcloud-micro-service.git
创建一个新的模块springcloud-micro-stream-provider,这模块负责生产一个消息
<dependencies>
<dependency>
<groupId>com.chjgroupId>
<artifactId>springcloud-micro-apiartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-streamartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-stream-rabbitartifactId>
dependency>
dependencies>
server:
port: 8401
spring:
application:
name: springcloud-micro-stream-provider
cloud:
stream:
binders: # 在此处配置要绑定的rabbitmq的服务信息;
defaultRabbit: # 表示定义的名称,用于于binding整合
type: rabbit # 消息组件类型
environment: # 设置rabbitmq的相关的环境配置
spring:
rabbitmq:
addresses: localhost
port: 5672
username: admin
password: admin
virtual-host: /
bindings: # 服务的整合处理
output: # 这个名字是一个通道的名称,在分析具体源代码的时候会进行说明
destination: HnakinExchange # 表示要使用的Exchange名称定义
content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain”
binder: defaultRabbit # 设置要绑定的消息服务的具体设置
public interface IMessageProvider {
void send(Product product);
}
stream-provider定义接口的实现类:
package com.chj.service.impl;
import com.chj.service.IMessageProvider;
import com.chj.vo.Product;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.messaging.MessageChannel;
import javax.annotation.Resource;
@EnableBinding(Source.class)
public class MessageProviderImpl implements IMessageProvider {
@Resource
private MessageChannel output; // 消息的发送管道
@Override
public void send(Product product) {
output.send(MessageBuilder.withPayload(product).build());
}
}
@SpringBootApplication
public class StreamProviderApp {
public static void main(String[] args) {
SpringApplication.run(StreamProviderApp.class,args);
}
}
@SpringBootTest(classes = StreamProviderApp.class)
@RunWith(SpringRunner.class)
public class TestMessageProvider {
@Resource
private IMessageProvider messageProvider;
@Test
public void testSend() {
Product product = new Product();
product.setProductId(1L);
product.setProductName("messageName");
product.setProductDesc("test springcloud stream message");
messageProvider.send(product);
}
}
查看RabbitMQ控制台:http://localhost:15672/,已经产生了个消息:
对于RabbitMQ来说,在这默认的Exchange的类型是Topic。
新建模块springcloud-micro-stream-consumer,作为消息的消费者。
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-streamartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-stream-rabbitartifactId>
dependency>
<dependency>
<groupId>com.chjgroupId>
<artifactId>springcloud-micro-apiartifactId>
dependency>
dependencies>
server:
port: 8402
spring:
application:
name: springcloud-micro-stream-consumer
cloud:
stream:
binders: # 在此处配置要绑定的rabbitmq的服务信息;
defaultRabbit: # 表示定义的名称,用于于binding整合
type: rabbit # 消息组件类型
environment: # 设置rabbitmq的相关的环境配置
spring:
rabbitmq:
addresses: localhost
port: 5672
username: admin
password: admin
virtual-host: /
bindings: # 服务的整合处理
input: # 这个名字是一个通道的名称,在分析具体源代码的时候会进行说明
destination: HnakinExchange # 表示要使用的Exchange名称定义
content-type: application/json # 设置消息类型,本次为对象json,如果是文本则设置“text/plain”
binder: defaultRabbit # 设置要绑定的消息服务的具体设置
@Component
@EnableBinding(Sink.class)
public class MessageListener {
@StreamListener(Sink.INPUT)
public void input(Message
System.err.println("【*** 消息接收 ***】" + message.getPayload());