首先创建两个spring cloud项目,一个项目为生产者项目,一个项目为消费者项目
在两个项目中引入stream的包
这里使用的是rabbitMq的包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
</dependency>
然后配置文件中添加mq相关配置
spring
rabbitmq:
host: 127.0.0.1
port: 5672
username: guest
password: guest
这时启动项目,启动日志中会出现类似以下日志,说明rabbitMq连接成功
Attempting to connect to: [127.0.0.1:5672]
Created new connection: rabbitConnectionFactory#28068327:0/SimpleConnection@55fbebba [delegate=amqp://guest@127.0.0.1:5672/, localPort= 51415]
现在在生产者项目中创建一个生产者
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.Output;
import org.springframework.cloud.stream.messaging.Source;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.support.MessageBuilder;
import java.util.UUID;
@EnableBinding(Source.class)
public class Producer {
@Autowired
@Output(Source.OUTPUT)
private MessageChannel channel;
public void send() {
channel.send(MessageBuilder.withPayload("22222222222" + UUID.randomUUID().toString()).build());
}
}
在消费者项目中创建一个消费者
import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.stream.annotation.EnableBinding;
import org.springframework.cloud.stream.annotation.StreamListener;
import org.springframework.cloud.stream.messaging.Sink;
import org.springframework.messaging.Message;
@EnableBinding(Sink.class)
public class Consumer {
@StreamListener(Sink.INPUT)
public void receive(Message<String> message) {
System.out.println("接收到MQ消息:" + JSONObject.toJSONString(message));
}
}
这里我用的stream提供的接口,也可以自定义
public interface Sink {
String INPUT = "input";
@Input(Sink.INPUT)
SubscribableChannel input();
}
public interface Source {
String OUTPUT = "output";
@Output("output")
MessageChannel output();
}
复制以上两个类的代码并修改INPUT或者OUTPUT便可完成自定义接口
需要注意的是INPUT和OUTPUT的值会在配置文件中做配置,不然你会发现项目没报错,消息也发出去了,但是收不到,这里非常重要
官方文档也有说明
setting the application property spring.cloud.stream.bindings.input.destination to raw-sensor-data will cause it to read from the raw-sensor-data Kafka topic, or from a queue bound to the raw-sensor-data RabbitMQ exchange
在生产者项目配置文件中添加
spring
cloud:
stream:
bindings:
output:
destination: my-test-channel
在消费者项目配置文件中添加
spring
cloud:
stream:
bindings:
input:
destination: my-test-channel
这里的input和output分别对应上面的Sink.INPUT和Source.OUTPUT
在生产者项目中创建一个controller,将Producer自动注入,写一个get或post调用Producer.send
重启两个项目,调用Producer.send,这时消费者项目控制台会打印
接收到MQ消息:{"headers":{"amqp_receivedDeliveryMode":"PERSISTENT","amqp_receivedRoutingKey":"my-test-channel","amqp_receivedExchange":"my-test-channel","amqp_deliveryTag":1,"amqp_consumerQueue":"my-test-channel.anonymous.vYA2O6ZSQE-S9MOnE0ZoJQ","amqp_redelivered":false,"id":"805e7fc3-a046-e07a-edf5-def58d9c8eab","amqp_consumerTag":"amq.ctag-QwsmRKg5f0DGSp-7wbpYxQ","contentType":"text/plain","timestamp":1523930106483},"payload":"22222222222a7d24456-5b11-4c25-9270-876e7bbc556a"}
说明测试成功
这里还有一点需要注意,我之前没注意踩了个坑,在项目完全启动好之前,可能会存在加载顺序不一致,我在controller中自动注入了一个方法来调用Producer.send,结果项目启动失败,原因就是rabbitMq的相关配置还没完全初始化,把调用放在get请求方法中等项目启动完成就可以调用了