我可以在执行时更改弹簧参数吗?

时间:2018-12-12 11:35:31

标签: java spring rabbitmq spring-rabbitmq

我有一个使用动态使用者的应用程序。我正在将Spring Framework与RabbitMQ结合使用。

我有concurrentConsumersmaxConcurrentConsumers之类的参数。

这是一个示例:

@Bean 
public SimpleMessageListenerContainer container(ConnectionFactory connection) {
    SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();

    container.setMaxConcurrentConsumers(8);
    container.setConcurrentConsumers(1);

    return container;
}

运行应用程序时可以更改值吗?例如,如果我希望使用5 maxConcurrentConsumers而不是8,可以在应用程序运行时更改终端上的值或类似的值吗?

1 个答案:

答案 0 :(得分:1)

您的bean是单例的,应该是无状态的(至少是不可变的或实际上是无状态的),以确保线程安全性和正确性。

  

通常,应将原型作用域用于所有有状态Bean,将单例作用域用于无状态Bean。

     

Spring documentation

有时,创建Bean的成本非常高,因此一次构造一个实例,然后保证对该对象进行的所有可能更改将以安全,正确的方式渗透到其所有消费者上更为合理。

>

我建议建立一个简单的事件驱动机制。

  • 一个MessageListenerContainerEvent extends ApplicationEvent,代表对MessageListenerContainer bean所做的更改;
  • 一个MessageListenerContainerChanger implements ApplicationListener<MessageListenerContainerEvent>是一个修改Bean状态并确保一切正常的侦听器;
  • 使用bean且对保持其最新状态感兴趣的其他类的侦听器。不必将更改发送给bean使用者,您可以不带任何消息通知它们。对于他们来说,这意味着他们在本地使用的Bean的某些属性可能已过时。
  • 可以是HTTP端点或@ShellMethod的发布者。

它看起来太复杂了,您总是可以简化为

// somewhere in your code
synchronized(bean) {
    bean.setConcurrentConsumers(10);
}

但是请记住此代码段传播的正确性。