Spring AMQP Rabbit 侦听器在 "ApplicationReadyEvent" 之前触发
Spring AMQP Rabbit listener firing before "ApplicationReadyEvent"
在 Spring 应用程序启动时,我想在 Redis
中查找一个值,并根据该值我想关闭或保留我拥有的消息侦听器。
也可以完全不初始化这些 bean,但我找不到任何一种方法。
目前,我正在尝试使用 Spring 的 ApplicationReadyEvent
:
关闭容器
@Component
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {
private @Autowired @Qualifier("completedOrderContainer") SimpleMessageListenerContainer container;
private @Autowired RedisManagerImpl redis;
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
if (!Boolean.valueOf(redis.isRabbitListenerActive())) container.shutdown();
}
}
容器和 AMQP bean 初始化如下:
@Bean
@Conditional(RabbitCondition.class)
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(rabbitHost + ":" + rabbitPort);
connectionFactory.setUsername(rabbitUsername);
connectionFactory.setPassword(rabbitPassword);
return connectionFactory;
}
@Bean
@Conditional(RabbitCondition.class)
Queue completedOrderQueue() {
return new Queue(completedOrderQueueName, true);
}
@Bean
@Conditional(RabbitCondition.class)
TopicExchange completedOrderExchange() {
return new TopicExchange(completedOrderExchangeName);
}
@Bean
@Conditional(RabbitCondition.class)
Binding binding(Queue completedOrderQueue, TopicExchange completedOrderExchange) {
return BindingBuilder.bind(completedOrderQueue).to(completedOrderExchange).with(completedOrderQueueName);
}
@Bean
@Conditional(RabbitCondition.class)
SimpleMessageListenerContainer completedOrderContainer(ConnectionFactory connectionFactory, MessageListenerAdapter completedOrderListenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(completedOrderQueueName);
container.setMessageListener(completedOrderListenerAdapter);
return container;
}
@Bean
@Conditional(RabbitCondition.class)
MessageListenerAdapter completedOrderListenerAdapter(CompletedOrderMessageReceiver receiver) {
return new MessageListenerAdapter(receiver, "completedOrder");
}
消息侦听器:
@Component
public class CompletedOrderMessageReceiver {
public void completedOrder(Object asyncTask) throws Exception {
//impl
}
}
问题是,如果我启动应用程序时消息已经在队列中,消息侦听器将在 container.shutdown()
执行之前获取消息。
有没有办法实现我的目标?即使采用不同的方法
在侦听器容器上将 autoStartup
设置为 false
。然后根据需要 start()
和 stop()
。
在 Spring 应用程序启动时,我想在 Redis
中查找一个值,并根据该值我想关闭或保留我拥有的消息侦听器。
也可以完全不初始化这些 bean,但我找不到任何一种方法。
目前,我正在尝试使用 Spring 的 ApplicationReadyEvent
:
@Component
public class ApplicationStartup implements ApplicationListener<ApplicationReadyEvent> {
private @Autowired @Qualifier("completedOrderContainer") SimpleMessageListenerContainer container;
private @Autowired RedisManagerImpl redis;
@Override
public void onApplicationEvent(ApplicationReadyEvent event) {
if (!Boolean.valueOf(redis.isRabbitListenerActive())) container.shutdown();
}
}
容器和 AMQP bean 初始化如下:
@Bean
@Conditional(RabbitCondition.class)
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(rabbitHost + ":" + rabbitPort);
connectionFactory.setUsername(rabbitUsername);
connectionFactory.setPassword(rabbitPassword);
return connectionFactory;
}
@Bean
@Conditional(RabbitCondition.class)
Queue completedOrderQueue() {
return new Queue(completedOrderQueueName, true);
}
@Bean
@Conditional(RabbitCondition.class)
TopicExchange completedOrderExchange() {
return new TopicExchange(completedOrderExchangeName);
}
@Bean
@Conditional(RabbitCondition.class)
Binding binding(Queue completedOrderQueue, TopicExchange completedOrderExchange) {
return BindingBuilder.bind(completedOrderQueue).to(completedOrderExchange).with(completedOrderQueueName);
}
@Bean
@Conditional(RabbitCondition.class)
SimpleMessageListenerContainer completedOrderContainer(ConnectionFactory connectionFactory, MessageListenerAdapter completedOrderListenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames(completedOrderQueueName);
container.setMessageListener(completedOrderListenerAdapter);
return container;
}
@Bean
@Conditional(RabbitCondition.class)
MessageListenerAdapter completedOrderListenerAdapter(CompletedOrderMessageReceiver receiver) {
return new MessageListenerAdapter(receiver, "completedOrder");
}
消息侦听器:
@Component
public class CompletedOrderMessageReceiver {
public void completedOrder(Object asyncTask) throws Exception {
//impl
}
}
问题是,如果我启动应用程序时消息已经在队列中,消息侦听器将在 container.shutdown()
执行之前获取消息。
有没有办法实现我的目标?即使采用不同的方法
在侦听器容器上将 autoStartup
设置为 false
。然后根据需要 start()
和 stop()
。