我最近开始学习Spring和spring-amqp所以这个问题可能看起来很基本所以请原谅我。
我有多个队列,它们位于不同的主机上,并具有不同的QueueName,RoutingKey,vhost,user,password。我正在为这些队列编写发布逻辑,但无法确定每个队列是否应该有一个配置类,还是可以用XML完成。
创建类以获取有关队列的所有信息(主机,vhost,用户名等)的方法正常工作,如this example中所述。 我创建了一个@Configuration类,并为该Queue定义了所有bean。但后来我需要做
ApplicationContext context = new AnnotationConfigApplicationContext(MyQueueConfiguration.class);
AmqpTemplate amqpTemplate = context.getBean(AmqpTemplate.class);
amqpTemplate.convertAndSend("Hello World!!");
所以我的要求是:
因此,对于每个队列,我总是需要这样做:
ApplicationContext context = new AnnotationConfigApplicationContext(HelloWorldConfiguration.class);
或者有没有办法让Spring加载我的所有Queue配置类,只需使用像:
这样的对象 // calling code when I get a POST request
MyQueueConfigurationClass.publishMessage(payload, queueName);
// The implementation code
public boolean publishMessage(String payload, String queueName){
// Get Bean for the **queueName** somehow
AmqpTemplate amqpTemplate = context.getBean(AmqpTemplate.class);
// Use the bean to send the message
amqpTemplate.convertAndSend(payload);
}
new AnnotationConfigApplicationContext()
的情况下每次都获取确切队列的amqpTemplate?答案 0 :(得分:3)
每次都不应该创建新的上下文;这非常浪费。
您可以将多个连接工厂(每个兔主机一个)添加到根(或Web)上下文,然后使用Routing Connection Factory和sendConnectionFactorySelectorExpression
来选择适当的主机基于你发送的消息。
或者,您可以为每个服务器简单地连接不同的RabbitTemplate
。
修改强>:
要使用SimpleRoutingConnectionFactory
,请执行类似......
try {
SimpleResourceHolder.bind(routingCF, keyForThisMessage);
rabbitTemplate.convertAndSend(message);
}
finally {
SimpleResourceHolder.unbind(routingCF);
}
(这适用于未经修改的RabbitTemplate
)或......
<rabbit:template id="routingTemplate"
connection-factory="rcf"
send-connection-factory-selector-expression="messageProperties.headers['cfKey']" />
<bean id="rcf" class="org.springframework.amqp.rabbit.connection.SimpleRoutingConnectionFactory">
<property name="targetConnectionFactories">
<map>
<entry key="foo" value-ref="cf1"/>
<entry key="bar" value-ref="cf2"/>
</map>
</property>
<property name="defaultTargetConnectionFactory" ref="defaultCF"/>
</bean>
......然后......
this.routingTemplate.convertAndSend("exchange", "routingKey", "xyz", new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setHeader("cfKey", "foo");
return message;
}
});
有一个完整的测试用例here。