springBoot整合rabbitMQ,通过注册bean的方式创建exchange,queue,容器中成功注入,但rabbitserver中不显示

一:解决办法
1、添加一个监听器
@RabbitListener(queues = "你的队列名")
public void handle(Message message){

}
2、或者加入如下bean创建一个connection 
@Bean
ApplicationRunner runner(ConnectionFactory cf) {
    return args -> cf.createConnection().close();
}



二原理:
因为在rabbitMQ采用的是懒加载, connection 启动时不会创建,下面第6步的 ConnectionListener 为空,因此需要创建一个连接,通过 ConnectionFactory接口 调用createConnection()方法创建一个连接注册到容器中
public interface ConnectionFactory {
    Connection createConnection() throws AmqpException;
public interface ConnectionListener {
    void onCreate(Connection var1);

    default void onClose(Connection connection) {
    }

    default void onShutDown(ShutdownSignalException signal) {
    }

    default void onFailed(Exception exception) {
    }
}
 

下面为springboot为自动创建rabbit的交换机,队列,绑定关系的原理

1、springBoot自动帮助我们创建RabbitMQ的Queue和Exchange是通过 RabbitAutoConfiguration类

@AutoConfiguration
@ConditionalOnClass({ RabbitTemplate.class, Channel.class })
@EnableConfigurationProperties(RabbitProperties.class)
@Import({ RabbitAnnotationDrivenConfiguration.class, RabbitStreamConfiguration.class })
public class RabbitAutoConfiguration

2、该类中注入了AmqpAdmin,可以看到是通过RabbitAdmin方法创建的连接

@Bean
		@ConditionalOnSingleCandidate(ConnectionFactory.class)
		@ConditionalOnProperty(prefix = "spring.rabbitmq", name = "dynamic", matchIfMissing = true)
		@ConditionalOnMissingBean
		public AmqpAdmin amqpAdmin(ConnectionFactory connectionFactory) {
			return new RabbitAdmin(connectionFactory);
		}

3、查看 RabbitAdmin类,可以看到实现了InitializingBean接口,这个接口是用于实例化bean


@ManagedResource(
    description = "Admin Tasks"
)
public class RabbitAdmin implements AmqpAdmin, ApplicationContextAware, ApplicationEventPublisherAware, BeanNameAware, InitializingBean

4、查看InitializingBean接口,只有afterPropertiesSet一个接口

package org.springframework.beans.factory;

public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}

5、查看RabbitAdmin中是如何实现这个接口

 public void afterPropertiesSet() {
        synchronized(this.lifecycleMonitor) {
            if (!this.running && this.autoStartup) {
                if (this.retryTemplate == null && !this.retryDisabled) {
                    this.retryTemplate = new RetryTemplate();
                    this.retryTemplate.setRetryPolicy(new SimpleRetryPolicy(5));
                    ExponentialBackOffPolicy backOffPolicy = new ExponentialBackOffPolicy();
                    backOffPolicy.setInitialInterval(1000L);
                    backOffPolicy.setMultiplier(2.0D);
                    backOffPolicy.setMaxInterval(5000L);
                    this.retryTemplate.setBackOffPolicy(backOffPolicy);
                }

                if (this.connectionFactory instanceof CachingConnectionFactory && ((CachingConnectionFactory)this.connectionFactory).getCacheMode() == CacheMode.CONNECTION) {
                    this.logger.warn("RabbitAdmin auto declaration is not supported with CacheMode.CONNECTION");
                } else {
                    AtomicBoolean initializing = new AtomicBoolean(false);
                    this.connectionFactory.addConnectionListener((connection) -> {
                        if (initializing.compareAndSet(false, true)) {
                            try {
                                if (this.retryTemplate != null) {
                                    this.retryTemplate.execute((c) -> {
                                        this.initialize();
                                        return null;
                                    });
                                } else {
                                    this.initialize();
                                }
                            } finally {
                                initializing.compareAndSet(true, false);
                            }

                        }
                    });
                    this.running = true;
                }
            }
        }
    }

6、可以看到连接工厂添加了一个连接监听器,在里面调用了initalize方法

this.connectionFactory.addConnectionListener((connection) -> {
                        if (initializing.compareAndSet(false, true)) {
                            try {
                                if (this.retryTemplate != null) {
                                    this.retryTemplate.execute((c) -> {
                                        this.initialize();
                                        return null;
                                    });
                                } else {
                                    this.initialize();
                                }
                            } finally {
                                initializing.compareAndSet(true, false);
                            }

                        }
                    });

7、查看initialize方法

 public void initialize() {
        if (this.applicationContext == null) {
            this.logger.debug("no ApplicationContext has been set, cannot auto-declare Exchanges, Queues, and Bindings");
        } else {
            this.logger.debug("Initializing declarations");
            Collection<Exchange> contextExchanges = new LinkedList(this.applicationContext.getBeansOfType(Exchange.class).values());
            Collection<Queue> contextQueues = new LinkedList(this.applicationContext.getBeansOfType(Queue.class).values());
            Collection<Binding> contextBindings = new LinkedList(this.applicationContext.getBeansOfType(Binding.class).values());
            Collection<DeclarableCustomizer> customizers = this.applicationContext.getBeansOfType(DeclarableCustomizer.class).values();
            this.processDeclarables(contextExchanges, contextQueues, contextBindings);
            Collection<Exchange> exchanges = this.filterDeclarables(contextExchanges, customizers);
            Collection<Queue> queues = this.filterDeclarables(contextQueues, customizers);
            Collection<Binding> bindings = this.filterDeclarables(contextBindings, customizers);
            Iterator var8 = exchanges.iterator();

            while(true) {
                Exchange exchange;
                do {
                    if (!var8.hasNext()) {
                        var8 = queues.iterator();

                        while(true) {
                            Queue queue;
                            do {
                                if (!var8.hasNext()) {
                                    if (exchanges.size() == 0 && queues.size() == 0 && bindings.size() == 0 && this.manualDeclarables.size() == 0) {
                                        this.logger.debug("Nothing to declare");
                                        return;
                                    }

                                    this.rabbitTemplate.execute((channel) -> {
                                        this.declareExchanges(channel, (Exchange[])exchanges.toArray(new Exchange[exchanges.size()]));
                                        this.declareQueues(channel, (Queue[])queues.toArray(new Queue[queues.size()]));
                                        this.declareBindings(channel, (Binding[])bindings.toArray(new Binding[bindings.size()]));
                                        return null;
                                    });
                                    if (this.manualDeclarables.size() > 0) {
                                        synchronized(this.manualDeclarables) {
                                            this.logger.debug("Redeclaring manually declared Declarables");
                                            Iterator var14 = this.manualDeclarables.values().iterator();

                                            while(var14.hasNext()) {
                                                Declarable dec = (Declarable)var14.next();
                                                if (dec instanceof Queue) {
                                                    this.declareQueue((Queue)dec);
                                                } else if (dec instanceof Exchange) {
                                                    this.declareExchange((Exchange)dec);
                                                } else {
                                                    this.declareBinding((Binding)dec);
                                                }
                                            }
                                        }
                                    }

                                    this.logger.debug("Declarations finished");
                                    return;
                                }

                                queue = (Queue)var8.next();
                            } while(queue.isDurable() && !queue.isAutoDelete() && !queue.isExclusive());

                            if (this.logger.isInfoEnabled()) {
                                this.logger.info("Auto-declaring a non-durable, auto-delete, or exclusive Queue (" + queue.getName() + ") durable:" + queue.isDurable() + ", auto-delete:" + queue.isAutoDelete() + ", exclusive:" + queue.isExclusive() + ". It will be redeclared if the broker stops and is restarted while the connection factory is alive, but all messages will be lost.");
                            }
                        }
                    }

                    exchange = (Exchange)var8.next();
                } while(exchange.isDurable() && !exchange.isAutoDelete());

                if (this.logger.isInfoEnabled()) {
                    this.logger.info("Auto-declaring a non-durable or auto-delete Exchange (" + exchange.getName() + ") durable:" + exchange.isDurable() + ", auto-delete:" + exchange.isAutoDelete() + ". It will be deleted by the broker if it shuts down, and can be redeclared by closing and reopening the connection.");
                }
            }
        }
    }

8、可以看到,底层还是RabbitAdmin 在执行声明交换机,队列,绑定关系

this.rabbitTemplate.execute((channel) -> {
                                        this.declareExchanges(channel, (Exchange[])exchanges.toArray(new Exchange[exchanges.size()]));
                                        this.declareQueues(channel, (Queue[])queues.toArray(new Queue[queues.size()]));
                                        this.declareBindings(channel, (Binding[])bindings.toArray(new Binding[bindings.size()]));
                                        return null;
                                    });

9、进入declareExchanges 方法

    private void declareExchanges(Channel channel, Exchange... exchanges) throws IOException {
        Exchange[] var3 = exchanges;
        int var4 = exchanges.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            Exchange exchange = var3[var5];
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("declaring Exchange '" + exchange.getName() + "'");
            }

            if (!this.isDeclaringDefaultExchange(exchange)) {
                try {
                    if (exchange.isDelayed()) {
                        Map<String, Object> arguments = exchange.getArguments();
                        HashMap arguments;
                        if (arguments == null) {
                            arguments = new HashMap();
                        } else {
                            arguments = new HashMap(arguments);
                        }

                        arguments.put("x-delayed-type", exchange.getType());
                        channel.exchangeDeclare(exchange.getName(), "x-delayed-message", exchange.isDurable(), exchange.isAutoDelete(), exchange.isInternal(), arguments);
                    } else {
                        channel.exchangeDeclare(exchange.getName(), exchange.getType(), exchange.isDurable(), exchange.isAutoDelete(), exchange.isInternal(), exchange.getArguments());
                    }
                } catch (IOException var8) {
                    this.logOrRethrowDeclarationException(exchange, "exchange", var8);
                }
            }
        }

    }

10、可以看到最底层调用了channel接口的实现

channel.exchangeDeclare(exchange.getName(), "x-delayed-message", exchange.isDurable(), exchange.isAutoDelete(), exchange.isInternal(), arguments);

11、可以进入Channel接口查看:

DeclareOk exchangeDeclare(String var1, String var2) throws IOException;

    DeclareOk exchangeDeclare(String var1, BuiltinExchangeType var2) throws IOException;

    DeclareOk exchangeDeclare(String var1, String var2, boolean var3) throws IOException;

    DeclareOk exchangeDeclare(String var1, BuiltinExchangeType var2, boolean var3) throws IOException;

    DeclareOk exchangeDeclare(String var1, String var2, boolean var3, boolean var4, Map<String, Object> var5) throws IOException;

    DeclareOk exchangeDeclare(String var1, BuiltinExchangeType var2, boolean var3, boolean var4, Map<String, Object> var5) throws IOException;

    DeclareOk exchangeDeclare(String var1, String var2, boolean var3, boolean var4, boolean var5, Map<String, Object> var6) throws IOException;

    DeclareOk exchangeDeclare(String var1, BuiltinExchangeType var2, boolean var3, boolean var4, boolean var5, Map<String, Object> var6) throws IOException;

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 可以通过 AMQP(高级消息队列协议)来实现与 RabbitMQ 的集成。下面是整合的步骤: 1. 添加 RabbitMQ 依赖 在 `pom.xml` 文件添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 2. 配置 RabbitMQ 连接信息 在 `application.properties` 文件添加以下配置: ```properties spring.rabbitmq.host=your-rabbitmq-server-hostname spring.rabbitmq.port=5672 spring.rabbitmq.username=your-rabbitmq-username spring.rabbitmq.password=your-rabbitmq-password ``` 3. 创建消息发送者和接收者 在 Spring Boot ,可以通过 `RabbitTemplate` 来发送和接收消息。下面是一个简单的发送者和接收者示例: ```java @Component public class MessageSender { @Autowired private RabbitTemplate rabbitTemplate; public void send(String message) { rabbitTemplate.convertAndSend("my-exchange", "my-routing-key", message); } } @Component public class MessageReceiver { @RabbitListener(queues = "my-queue") public void receive(String message) { System.out.println("Received message: " + message); } } ``` 4. 配置交换机和队列 在 RabbitMQ ,消息发送和接收都需要通过交换机和队列来完成。在 Spring Boot ,可以通过 `org.springframework.amqp.core` 包的类来创建交换机和队列。以下是一个简单的配置示例: ```java @Configuration public class RabbitMQConfig { @Bean public DirectExchange myExchange() { return new DirectExchange("my-exchange"); } @Bean public Queue myQueue() { return new Queue("my-queue"); } @Bean public Binding binding() { return BindingBuilder.bind(myQueue()).to(myExchange()).with("my-routing-key"); } } ``` 以上就是 Spring Boot 整合 RabbitMQ 的基本步骤。通过这种方式,我们可以在 Spring Boot 应用程序轻松地集成 RabbitMQ,实现消息的发送和接收。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值