Ao usar o Spring Boot + RabbitMQ, você pode desativar/ativar temporariamente a escuta ou modificar o número de consumidores de escuta durante o desenvolvimento. Se você reiniciar a cada vez, é uma perda de tempo, por isso estudei para permitir a desativação de ouvir ou modificar algumas configurações sem desligar.
1. Sobre a configuração da audição de RabbitMQ
@Configuration@condicionalOnClass ({rabbittemplate.class, canal.class})@EnableConfigurationProperties (rabbitproperties.class) @import (rabbitannotationdrivenconfiguration.class) classe pública rabbitautoconfiguration {}} O RabbitannotationDrivenconfiguration se concentra principalmente no monitoramento da configuração da fábrica e no monitoramento da fábrica, mas aqui está apenas criando feijões, e não há inicialização real.
Através do nome da classe Bean na configuração, analise -o. A escuta do RabbitMQ deve ser criada pela fábrica de audição, então encontre a fábrica de audição simples
@Bean@condicionalonMissingBean (name = "rabbitListEnerContainerFactory") public SimpleRabbitListEnerContainerFactory RabbitListEnerContainerFactFactory (SimpleRabbitListErContAnnerFactoryCigrover Configator, ConnectionFactory) {SIMPLEFENSPLATLISTERCONTERSERCIMER Configurer.Configure (Factory, ConnectionFactory); Fábrica de retorno;} Como não há nenhuma audição inicial na configuração automática, ele deve ser chamado em outros lugares. Ao entrar na classe de fábrica de escuta, descobri que existe o método InitializeContainer (Instância SimpleMessageListerContainer). Eu acho que a inicialização deve estar relacionada a esse método, por isso verifico quais lugares são chamados, então descobri que o RabbitListenendpoIntRegistry.CreatElistEnerContainer (RabbitListenendPoint Endpoint, RabbitListEnerContAinerFactory <?> Factory) Método tem o código para criar o contêiner de escuta e a inicialização.
/*** Crie e inicie um novo {@link messagelistenerContainer} usando a fábrica especificada. * @param endpoint O endpoint para criar um {@link messagelistenerContainer}. * @Param Factory the {@link rabbitListeneContainerFactory} para usar. * @return the {@link messagelistenerContainer}. */protegido messagelistEnerContainer CreateListEnerContainer (RabbitListenendPoint endpoint, RabbitListEnerContainerFactory <?> if (ouvidos a instância do InitializingBean) {try {((InitializingBean) ListenContainer) .AFterPropertiESSET (); } catch (Exceção ex) {lança nova beaninitializationException ("Falha ao inicializar o contêiner do ouvinte de mensagens", ex); }} int containerPhase = listenContainer.getPhase (); if (containerphase <Integer.max_value) {// Um valor de fase personalizado se (this.phase <Integer.max_value && this.phase! = containerphase) {lançar new ilegalstateException ("Encontro de fase de fase entre as definições de fábrica de contêineres:" + this.phase + "vs" +fase "+fase +; } this.Phase = ListenContainer.getPhase (); } Retornar ListenContainer;}Continue encontrando o local para chamar esse método. Depois de encontrar o método RabbitListenendpoIntregistrar.afterPropertiesset (), descobri que há muitos lugares para chamá -lo.
Vamos dar uma olhada no método AfterPropertiEsset, que está na interface InitializingBean. Acredita -se que seja o método de inicialização do feijão que será chamado depois que o contêiner da mola criar o feijão, então encontre onde o RabbitListenendpointregistrar foi criado. Acontece que é uma propriedade privada no RabbitListenenotationBeanPostProcessor, e o RabbitListeneRannotationBeanPostProcessor é inicializado na configuração automática do RabbitBootStrapconfiguration, para que encontre a fonte da audição inicial do rabbitmq
2. Gerenciamento dinâmico do monitoramento do RabbitMQ
Voltando à pergunta inicial, quero ativar dinamicamente a escuta do MQ desativar, então primeiro olho para a classe de configuração inicial. Como há inicialização, pode haver um gerenciamento relevante. Então, encontrei os métodos START () e STOP () no RabbitListenerendPoinTregistry, que opera no contêiner de escuta. O principal código -fonte é o seguinte
/*** @return the gerenciado {@link messagelistenerContainer} instância (s). */Coleção public <SsemaGelisteRerContainer> getListenerContainers () {return collectionS.unmodifiableCollection (this.ListenerContainers.Values ());} @OverridePublic void start () {for (MessagelistErSoRantainer @ListerContAinante: GetListerCerMerConsT () {for (MessagelisterContaiR) ListerContAinAner: GetListerConsT () {for (MessagelisterContaiR) ListerContAnner: GetListerCerSerCons. }}/** * Inicie o especificado {@link messagelistenerContainer} Se ele for iniciado * na inicialização ou quando o início for chamado explicitamente após a inicialização. * @See MessagelistEnerContainer#isautostartup () */private void startifneCessary (messagelistEnerContainer listerContainer) {if (this.ContextReFreshed || ouvidos ousContainer.isaUToTUP ()) {ListenerContAiner.START (); }}@Substeridepublic void stop () {for (messagelistenecontainer listerContainer: getListenerContainers ()) {ouvistarContainer.stop (); }} Escreva um controlador, injete o rabbitlistenendpoiTregistry e habilite e desative a operação de escuta usando start () e stop (). A instância do RabbitListenendPoinTregistry também pode obter o contêiner de escuta e modificar alguns parâmetros da escuta, como o número de consumidores. O código é o seguinte:
importar java.util.set; importar javax.annotation.resource; importar org.springframework.amqp.rabbit.listener.rabbitlistenerendpointRegistry; importação org.springframework.amqp.rabbit.listener.simpleMessaGelSerMerCainner; org.springframework.web.bind.annotation.requestmapping; importar org.springframework.web.bind.annotation.restcontroller; importar com.itopener.framework.resultmap;/** ** Criado por Fuwi.deng em julho de 24, 2017. classe RabbitMqController {@Resource Private RabbitListenerendPoinTregistry RabbitListenendpoIntRegistry; @RequestMapping ("STOP") public ResultMap stop () {rabbitListenendpoIntRegistry.stop (); return resultmap.buildSuccess (); } @ReQuestMapping ("Start") public ResultMap start () {rabbitListenerendpoIntRegistry.start (); return resultmap.buildSuccess (); } @RequestMapping ("Setup") Public ResultMap Setup (int consumer, int maxConsumer) {set <string> containerIds = rabbitListenerendpoIntRegistry.getListEnerContainerids (); SimpleMessaGelistEnerContainer Container = NULL; para (string id: containerIds) {container = (simplemessageListEnerContainer) rabbitListenerendpoIntRegistry.getListEnerContainer (id); if (contêiner! = null) {container.setConcurrentConsumers (consumidor); container.setMaxConcurrentConsumers (maxConsumer); }} retornar resultmap.buildSuccess (); }}O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.