我尝试使用TopicExchange来屏蔽消息。
配置:
<rabbit:connection-factory id="connectionFactory" host="localhost" username="guest" password="guest"/>
<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory"/>
<rabbit:queue name="sample.queue"/>
<rabbit:admin id="rabbitAdmin" connection-factory="connectionFactory" />
<bean id="rabbitListenerContainerFactory"
class="org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory">
<property name="connectionFactory" ref="connectionFactory"/>
</bean>
<rabbit:annotation-driven container-factory="rabbitListenerContainerFactory"/>
<rabbit:listener-container connection-factory="connectionFactory" />
组件:
@Component
public class JmsComponent {
private final Logger log = LoggerFactory.getLogger(JmsComponent.class);
private final TopicExchange exchange = new TopicExchange("sample.exchange");
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private Queue queue;
private String received;
public void send(String msg) {
rabbitTemplate.convertAndSend("sample.queue", new SimpleMessage(msg));
}
public void bindToKey(String keyMask) {
BindingBuilder.bind(queue).to(exchange).with(keyMask);
rabbitTemplate.setExchange(exchange.getName());
}
public void sendByKey(String key, String msg) {
rabbitTemplate.convertAndSend(exchange.getName(), key, new SimpleMessage(msg));
}
@RabbitListener(queues = "sample.queue")
public void handle(SimpleMessage message) {
log.info("================ Received " + message.getMsg());
received = message.getMsg();
}
public String getReceived() {
return received;
}
当我使用send(包括TopicExchange之前) - 一切正常。消息直接发送到队列,handle()已收到它。 但对于TopicExchange ....我尝试使用它:
@Test
public void bind() throws InterruptedException {
jmsComponent.bindToKey("qq");
jmsComponent.sendByKey("qq", "message");
Thread.sleep(5000);
Assert.isTrue("message".equals(jmsComponent.getReceived()));
}
测试总是失败但是在日志中我看到了这个 - DEBUG o.s.amqp.rabbit.core.RabbitTemplate - 在交换上发布消息[sample.exchange],routingKey = [qq] 怎么了??? 感谢
答案 0 :(得分:4)
此...
MediaMetadata mediaMetadata = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
mediaMetadata.addImage(new WebImage(Uri.parse(MyAppConfigBase.IMAGE_API_ENDPOINT + movieVideoItem.getImages().getKeyart())));
mediaMetadata.addImage(new WebImage(Uri.parse(MyAppConfigBase.IMAGE_API_ENDPOINT + movieVideoItem.getImages().getKeyart())));
mediaMetadata.putString(MediaMetadata.KEY_TITLE, movieVideoItem.getTitle());
mediaMetadata.putString(MediaMetadata.KEY_SUBTITLE, movieVideoItem.getDescription());
mediaMetadata.putString("movie-urls", url);
mediaMetadata.putString("content-type", movieVideoItem.getContent().getHighRes().getType());
MediaTrack englishSubtitle = new MediaTrack.Builder(1 /* ID */, MediaTrack.TYPE_TEXT)
.setName("English Subtitle")
.setSubtype(MediaTrack.SUBTYPE_CAPTIONS)
.setContentId(closedCaptionsUrl)
/* language is required for subtitle type but optional otherwise */
.setLanguage("en-US")
.build();
List tracks = new ArrayList();
tracks.add(englishSubtitle);
MediaInfo mediaInfo = new MediaInfo.Builder(url)
.setStreamDuration(movieVideoItem.getDuration())
.setStreamType(MediaInfo.STREAM_TYPE_NONE)
.setContentType(type)
.setMetadata(mediaMetadata)
.setMediaTracks(tracks)
.setCustomData(customData)
.build();
...除了创建一个BindingBuilder.bind(queue).to(exchange).with(keyMask);
对象然后扔掉它之外什么都不做。您需要获取该Binding
个对象并在管理员上调用Binding
。您还需要申报交换。
由于您的上下文中有管理员;最简单的方法是将declareBinding
添加到上下文(以及绑定)。请参阅the documentation。
<rabbit:exchange/>
顺便说一下,主题交换用于按键模式进行路由;如果您只想使用固定密钥路由/绑定,例如<rabbit:queue id="myQueue" name="sample.queue"/>
<topic-exchange name="sample.exchange">
<bindings>
<binding queue="myQueue" pattern="bucket.#"/>
</bindings>
</topic-exchange>
,则使用直接交换。请参阅RabbitMQ Tutorials。
答案 1 :(得分:2)
我改变了我对Gary Russell的组件使用答案:
我已添加
@Autowired
private RabbitAdmin rabbitAdmin;
@PostConstruct
public void init(){
rabbitAdmin.declareExchange(exchange);
}
并修改绑定方法:
public void bindToKey(String keyMask) {
Binding binding = BindingBuilder.bind(queue).to(exchange).with(keyMask);
rabbitAdmin.declareBinding(binding); // re-declare binding if mask changed
rabbitTemplate.setExchange(exchange.getName());
}
然后测试就开始了!
更多,我在运行时添加了更改绑定掩码:
@Test
public void bind() throws InterruptedException {
jmsComponent.bindToKey("qq");
jmsComponent.sendByKey("qq", "message");
Thread.sleep(5000);
Assert.isTrue("message".equals(jmsComponent.getReceived()));
jmsComponent.bindToKey("eeeee");
jmsComponent.sendByKey("eeeee", "message one");
Thread.sleep(5000);
Assert.isTrue("message one".equals(jmsComponent.getReceived()));
}
一切正常。