【Fifty Project - D32】
今日完成记录
Time | Plan | 完成情况 |
---|---|---|
12:00 - 17:30 | 小论文2 | √ |
17:30 - 18:30 | 羽毛球 | √ |
19:30 - 21:30 | 继续RabbitMQ学习 | √ |
21:30 - 22:30 | 打球 | √ |
22:30 - 23:00 | 记录 | √ |
短暂的写小论文时间又让我感受到了极致的窒息感,可能是拖延症DDL临近的压迫感吧QAQ,真的搞不来一点科研
今天的羽毛球打的很快乐,感觉对双打多了一点点理解,估计是这几天刷到的萝卜的视频啥的太多了还有邪恶老大爷hhhh
虽然明天老板请客吃饭很开心,但是为了吃这顿饭改签花了200QAQ,太贵了这顿饭哇
RabbitMQ
声明队列和交换机
前面学习了如何使用控制台新建队列和交换机,然而在实际操作中,如果都使用控制台操作,那么需要有一个文件来记录队列和交换机情况,在其他机器部署代码需要在控制台逐一创建队列,属实麻烦。因此SpringAMQP提供了基于配置和基于注解的队列、交换机声明方式
基于配置的队列和交换机声明
这个方法的核心是用JavaBean的方式管理创建的队列和交换机,有两种新建对象的方法,一种是直接new,一种是使用工厂模式创建。
不管使用哪种方法,都需要创建三个对象,Queue
消息队列, Exchange
交换机, Binding
绑定关系。代码如下
@Configuration
public class FanoutConfiguration {@Beanpublic FanoutExchange fanoutExchange1(){// 直接newreturn new FanoutExchange("df.fanout1");//使用交换机工厂创建
// return ExchangeBuilder.fanoutExchange("df.fanout").build();}@Beanpublic Queue fanoutQueue1(){return new Queue("df.fanout.queue1");
// return QueueBuilder.durable("fanout.queue1").build();}@Beanpublic Queue fanoutQueue2(){return new Queue("df.fanout.queue2");
// return QueueBuilder.durable("fanout.queue1").build();}@Beanpublic Binding fanoutBinding3(){return BindingBuilder.bind(fanoutQueue1()).to(fanoutExchange1());}@Beanpublic Binding fanoutBinding4(){return BindingBuilder.bind(fanoutQueue2()).to(fanoutExchange1());}}
这种方式的弊端在于,如果创建订阅型交换机,那么每个key需要创建一个binding,如下:一个消息队列绑定一个direct exchange的三个key就需要绑定三个binding,这将使得代码量急剧上升。
@Configuration
public class DirectConfiguration {@Bean public DirectExchange directExchange1(){return new DirectExchange("df.direct1");}@Beanpublic Queue directQueue1(){return new Queue("df.direct.queue1");}@Beanpublic Binding directExchange1Queue1BindingRed(){return BindingBuilder.bind(directQueue1()).to(directExchange1()).with("red");}@Beanpublic Binding directExchange1Queue1BindingBlue(){return BindingBuilder.bind(directQueue1()).to(directExchange1()).with("blue");}@Beanpublic Binding directExchange1Queue1BindingYellow(){return BindingBuilder.bind(directQueue1()).to(directExchange1()).with("yellow");}
}
基于注解的队列和交换机声明方式
这种方式写在消费者端,如下
@RabbitListener(bindings = @QueueBinding(key={"blue", "red"},value = @Queue(value="df.direct1.queue1"),exchange = @Exchange(value = "df.direct1", type = ExchangeTypes.DIRECT)))
public void listenDirectQueue1(String msg){System.out.println("消费者3收到了df.direct.queue1的消息:【" + msg +"】");try {Thread.sleep(200);} catch (InterruptedException e) {}
}
@RabbitListener(bindings = {@QueueBinding(value = @Queue(value = "df.topic.queue1"),exchange = @Exchange(value = "df.topic1", type = ExchangeTypes.TOPIC),key="*.top"),@QueueBinding(value = @Queue(value = "df.topic.queue2"),exchange = @Exchange(value = "df.topic2", type = ExchangeTypes.TOPIC),key="top.*")}
)
public void RabbitMQTopicListener(String msg){System.out.println(msg);
}
在实验中发现,原来topic exchange的通配符,只适用于“.”和“.”之间的整段通配,而不能部分通配,也就是“a.*.b”是合法的,但是"a.*b"是不合法的。因为"*b"通配符在一个单词(“.”和“.”之间的整段)内部使用通配符是不合法的。
消息转换器
- 默认消息转换器:默认JDK序列化和反序列化,可读性差、体积大
- JSON转换器:可读性强、体积小
需要引入maven坐标并且在启动类配置一个Bean
@Bean
public MessageConverter messageConverter(){// 1.定义消息转换器Jackson2JsonMessageConverter jackson2JsonMessageConverter = new Jackson2JsonMessageConverter();// 2.配置自动创建消息id,用于识别不同消息,也可以在业务中基于ID判断是否是重复消息jackson2JsonMessageConverter.setCreateMessageIds(true);return jackson2JsonMessageConverter;
}