我想在应用程序开始收集消息时将匿名队列绑定到扇出交换,但是消息的实际处理应该在稍后进行(在其他地方进行一些初始化之后)。 我尝试过:
@RabbitListener(autoStartup="false",
bindings = @QueueBinding(value = @Queue,
exchange = @Exchange(name="myexchange",
type=ExchangeTypes.FANOUT)))
public void processMessage(String message) {
}
但 autoStartup =" false" 不会将(匿名)队列绑定到交换机。
换句话说,我需要的是一旦应用程序启动就绑定到交换的匿名队列,并且只在以后开始阅读消息。 是否可以使用@RabbitListener?
更新 试图声明队列和交换,但队列没有添加到兔子,除非我也为它声明了RabbitListener:
@Configuration
public class AmqpConfig {
@Bean
RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
return new RabbitAdmin(connectionFactory);
}
@Bean
public FanoutExchange fanout() {
return new FanoutExchange("myexchange");
}
private static class ReceiverConfig {
@Bean
public Queue myQueue() {
return new AnonymousQueue();
}
@Bean
public Binding binding(FanoutExchange fanout, Queue myQueue) {
return BindingBuilder.bind(myQueue).to(fanout);
}
}
除非我还添加了@RabbitListener,否则它不会创建队列:
@Component
public class AmqpReceiver {
@RabbitListener(queues = "#{myQueue.name}")
public void receive(String in) throws InterruptedException {
}
}
答案 0 :(得分:2)
由于您没有启动侦听器,因此无法打开连接。
只要您在应用程序上下文中将队列,绑定和RabbitAdmin
定义为bean,您需要做的就是强制打开连接(Admin会侦听新连接并执行声明)。
只需致电createConnection()
上的CachingConnectionFactory
。
修改强>
@SpringBootApplication
public class So49401150Application {
public static void main(String[] args) {
SpringApplication.run(So49401150Application.class, args);
}
@Bean
ApplicationRunner runner(ConnectionFactory cf, RabbitTemplate template,
RabbitListenerEndpointRegistry registry) {
return args -> {
cf.createConnection().close(); // Admin does declarations here
template.convertAndSend("myexchange", "", "foo");
Thread.sleep(30_000);
registry.start();
};
}
@RabbitListener(autoStartup="false",
bindings = @QueueBinding(value = @Queue,
exchange = @Exchange(name="myexchange",
type=ExchangeTypes.FANOUT)))
public void processMessage(String message) {
System.out.println(message);
}
}