上篇《Spring集成RabbitMQ-配置消息服务》我们介绍了Spring AMQP中是如何声明AmqpAdmin以及利用AmqpAdmin实现类RabbitAdmin来创建queue和exchange的。这篇将接着上篇继续,说说有关队列Queue和转换器Exchange创建的那些事儿。
创建单个Queue和Exchange的API
从版本1.6开始,Spring AMQP就引入了及其方便易用的API用于创建并配置Queue和Exchange。下面就是通过Java配置类的方式创建的实例代码
通过QueueBuilder创建了一个名为“foo”的Queue
该队列是nonDurable即不是持久化的,一个临时的队列
该队列是一个排他的队列即exclusive
该队列通过withArgument设置了队列参数放入一个map集合中
同理,通过ExchangeBuilder创建了一个名为“foo”的direct类型的exchange
该exchange是自动删除的即autoDelete
该exchange也通过withArgument设置交换器的参数
两个Builder最终都通过build方法完成Queue和Exchange的创建
通过看源码,我们发现,这两个build方式内部调用的是对应的构造函数
从版本2.0之后,通过ExchangeBuilder创建的exchange都是durable的,即持久化的
如果想配置为非持久化的,可以通过调用方法.durable(false)进行设置
同时,无参的函数durable()也将不再对外提供使用
创建多个Queue和Exchange的API
从版本1.5之后,就能够方便的创建多个Queue或者Exchange了,下面同样是基于Java配置类方式的代码
通过代码可以发现,不仅可以批量的创建Queue和Exchange,而且还可以批量创建绑定关系并将其放进List集合中返回使用。
有关属性name和id的一个注意事项
在标签定义<rabbit:queue/>和<rabbit:exchange/>中的name标识了queue和exchange的名称,对于队列queue而言,如果在定义是没有填写name属性,则会默认创建一个上篇提到的AnonymousQueue。
在2.0版本之前,name同时具有声明为一个bean的名称的效果,等同于<bean>中的name一样,这会存在一些问题
它不允许queue和exchange使用相同的name
name也不支持SpEL表达式
从2.0版本之后,在你为这些标签声明name和id属性的时候,将不会将其视为bean的别名了。如果你想实现queue和exchange使用同样的name,那么需要加上id属性。
匿名队列AnonymousQueue
当你需要用到一个名称唯一的,自动删除的,排他性的队列,这时候AnonymousQueue就排上用场了,想比上篇提到的自动声明一个空字符串的队列,其有以下优势
当connection连接建立的时候,队列才被创建,但是也要等相对比较久的时间,需要等到所有的beans都就位,而且这些bean在使用的时候还需要知道队列的名称,这一套显然比较复杂繁琐
如果由于某种原因,服务挂了,这时候如果使用声明的queue,在服务重新启动后,队列的名称就会改变,但是对于AnonymousQueue有一点比较好的就是,服务会启动一个与之前一样名称的queue
那么AnonymousQueue是如何命名的呢,这就要说到匿名队列的命名策略了
anon1方法生成就是以“spring.gen-”开头的队列名,后面是通过UUID规则生成的,比如最终的队列名是这样的spring.gen-MRBv9sqISkuCiPfOYfpo4g
anon2方法生成就是以“foo”开头,并对UUID规则生成的序列进行了Base64编码得到的对列明
anon3方法生成就是纯UUID规则得到的名称,比如f20c818a-006b-4416-bf91-643590fedb0e
延迟消息交换机
从版本1.6之后就支持了Delayed Messge Exchange。可以通过下面的方式进行XML的配置
<rabbit:topic-exchange name="topic" delayed="true" />
如果要发送延时的消息,我们可以在MessageProperties中像这样声明
或者这样