在实际开发中我们需要监听场景,比如我们之前举的例子,两个系统,订单系统,和我们库存系统,他们交互都是通过交互
通过消息队列,某一个人下了单以后,将订单信息放到消息队列中,库存系统要实时监听队列里的内容,一旦有新的订单进来,
库存系统就要负责相关的操作,那我们的监听怎么写呢,Spring为了简化我么开发,给我们引入了相关的注解,比如我们来举一个
例子,我来写一个BookService,就来监听book里面的内容,我怎么写呢,我就叫receive,在这方法里面呢,我们要收到book的内容,
所以我在方法的参数上,我们这个方法是通过监听消息队列,可以来写一个注解,@RabbitListener,监听MQ的,那监听哪个消息队列呢,
我们可以来写一个queues,这个queues它是一个数组的方式,
/**
* The queues for this listener.
* The entries can be 'queue name', 'property-placeholder keys' or 'expressions'.
* Expression must be resolved to the queue name or {@code Queue} object.
* Mutually exclusive with {@link #bindings()}
* @return the queue names or expressions (SpEL) to listen to from target
* {@link org.springframework.amqp.rabbit.listener.MessageListenerContainer}.
*/
String[] queues() default {};
我们可以监听多个消息队列,我们就来监听我们之前的china.news,我们就来监听,有内容进来,@EnableRabbit,开启基于注解的MQ
package com.learn.service;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
import com.learn.bean.Book;
@Service
public class BookService {
@RabbitListener(queues="china.news")
public void receive(Book book) {
System.out.println("收到消息" + book);
}
}
package com.learn;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 自动配置
* @author Leon.Sun
*
*/
@SpringBootApplication
@EnableRabbit
public class SpringBoot02AmqpApplication {
public static void main(String[] args) {
// Spring应用启动起来
SpringApplication.run(SpringBoot02AmqpApplication.class,args);
}
}
有了这两个注解的配合,让@RabbitListener来监听Listener里的内容,监听消息队列的内容,我们就来启动一下这个应用,
来测试一下,只要有book信息来,我们就会收到,一启动就收到消息
收到消息Book [bookName=三国演义, author=罗贯中]
/**
* 广播
*/
@Test
public void sendMsg() {
rabbitTemplate.convertAndSend("exchange.fanout","",new Book("红楼梦","曹雪芹"));
}
收到消息Book [bookName=红楼梦, author=曹雪芹]
这就是我们收到消息监听来收消息,只要消息队列里有,这个我们直接序列化成Book对象,如果我们有一些定制的消息,
还想要消息头等等,写成Message类型
org.springframework.amqp.core.Message
写上Message类型以后呢,我们来写一个@RabbitListener,我们来监听china队列,我们写的Message参数,既有getBody消息的
内容,还有getMessageProperties,我们消息的头信息,我们可以重新尝试一下,我们来到这个主程序,他重新启动,来看china
里的内容,china默认已经有两个内容了,我们启动的时候都能收到,
[B@4511a7ef
MessageProperties [headers={__TypeId__=com.learn.bean.Book}, timestamp=null, messageId=null,
userId=null,
receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null,
correlationIdString=null,
replyTo=null, contentType=application/json, contentEncoding=UTF-8, contentLength=0,
deliveryMode=null,
receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false,
receivedExchange=exchange.fanout, receivedRoutingKey=, receivedDelay=null, deliveryTag=1,
messageCount=0,
consumerTag=amq.ctag-jmwvhNiVfS6HYqKWi5xuCw, consumerQueue=china]
[B@71e6aae7
MessageProperties [headers={__TypeId__=com.learn.bean.Book}, timestamp=null, messageId=null,
userId=null,
receivedUserId=null, appId=null, clusterId=null, type=null, correlationId=null,
correlationIdString=null,
replyTo=null, contentType=application/json, contentEncoding=UTF-8, contentLength=0,
deliveryMode=null,
receivedDeliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false,
receivedExchange=exchange.fanout, receivedRoutingKey=, receivedDelay=null,
deliveryTag=2,
messageCount=0, consumerTag=amq.ctag-jmwvhNiVfS6HYqKWi5xuCw, consumerQueue=china]
package com.learn.service;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Service;
import com.learn.bean.Book;
@Service
public class BookService {
@RabbitListener(queues="china.news")
public void receive(Book book) {
System.out.println("收到消息" + book);
}
@RabbitListener(queues="china")
public void receive02(Message message) {
System.out.println(message.getBody());
System.out.println(message.getMessageProperties());
}
}
package com.learn;
import org.springframework.amqp.rabbit.annotation.EnableRabbit;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 自动配置
* @author Leon.Sun
*
*/
@SpringBootApplication
@EnableRabbit
public class SpringBoot02AmqpApplication {
public static void main(String[] args) {
// Spring应用启动起来
SpringApplication.run(SpringBoot02AmqpApplication.class,args);
}
}
package com.learn.springboot;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import com.learn.bean.Book;
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringBootAmqpApplicationTests {
@Autowired
RabbitTemplate rabbitTemplate;
/**
* 1.单播(点对点)
*/
@Test
public void contextLoads() {
// Message需要自己构造一个,定义消息体内容和消息头
// rabbitTemplate.send(exchange, routingKey, message);
// object默认当成消息体,只需要传入要发送的对象,自动序列化发送给rabbitmq
// rabbitTemplate.convertAndSend(routingKey, message, messagePostProcessor);
Map<String,Object> map = new HashMap<String,Object>();
map.put("msg", "这是第一个消息");
map.put("data", Arrays.asList("helloworld",1231,true));
// 对象被默认序列化以后发送出去
rabbitTemplate.convertAndSend("exchange.direct", "china.news",new Book("西游记","吴承恩"));
}
@Test
public void receive() {
Object o = rabbitTemplate.receiveAndConvert("china.news");
System.out.println(o.getClass());
System.out.println(o);
}
/**
* 广播
*/
@Test
public void sendMsg() {
rabbitTemplate.convertAndSend("exchange.fanout","",new Book("红楼梦","曹雪芹"));
}
}