首页 > 技术文章 > RabbitMQ知识点整理5-声明交换器和队列

no-celery 原文

交换器和队列, 在应用程序使用它们的之前就已经存在了, 所以在使用之前要先声明它们

package demo.java.web.amqp.rabbitmq.demo2;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

import org.junit.Before;
import org.junit.Test;

import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * 声明交换器和队列
 * 
 * @author jiangkd
 * @date 2020/10/12
 */
public class DeclareExchangeAndQueueDemo {

    private Channel channel = null;

    final private String IP_ADDRESS = "127.0.0.1";
    final private int PORT = 5672;
    final private String USERNAME = "root";
    final private String PASSWORD = "root123";
    final private String VIRTUALHOST = "/jiangkd";

    final private String EXCHANGE_NAME = "exchange_demo";
final private String QUEUE_NAME = "queue_demo";
final private String ROUTING_KEY = "routingKey_demo"; @Before public void before() throws IOException, TimeoutException { // ConnectionFactory connectionFactory = new ConnectionFactory(); connectionFactory.setHost(IP_ADDRESS); connectionFactory.setPort(PORT); connectionFactory.setVirtualHost(VIRTUALHOST); connectionFactory.setUsername(USERNAME); connectionFactory.setPassword(PASSWORD); // 创建连接 Connection connection = connectionFactory.newConnection(); // 创建信道 channel = connection.createChannel(); } /** * 声明一个交换器和队列, 这里的交换器和队列没有设置特殊参数 * * @throws IOException */ @Test public void declareExchangeAndQueue() throws IOException { // 创建一个持久化的, 非自动删除的, 绑定类型是direct的交换器 channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, true); // 创建一个非持久化的, 排他的, 自动删除的队列(此队列的名称是由rabbitmq自动生成的) String queueName = channel.queueDeclare().getQueue(); // 使用绑定键(路由键)将交换机和队列绑定起来 channel.queueBind(queueName, EXCHANGE_NAME, ROUTING_KEY); } }

上面代码中声明的队列具备如下特性: 只对当前应用中同一个Connection层面可用, 同一个Connection的不同Channel可共用, 并且也会在应用连接断开时自动删除

如果要在应用中共享一个队列, 可以如下声明队列:

/**
 * 应用中共享一个队列
 * @throws IOException 
 */
@Test
public void declareExchangeAndQueue2() throws IOException {
    //
    channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.DIRECT, true);
    channel.queueDeclare(QUEUE_NAME, true, false, false, null);
    channel.queueBind(EXCHANGE_NAME, QUEUE_NAME, ROUTING_KEY);
}

这里的队列被声明为持久化的、非排他的、非自动删除的,而且也被分配另一个确定的已知的名称(由客户端分配而非RabbitMQ自动生成)

注意: Channel的API方法都是可以重载的, 比如exchangeDeclare, queueDeclare, 根据参数不同, 可以有不同的重载形式, 根据自身的需要进行调用

生产者和消费者都可以声明一个交换机或者队列, 如果尝试声明一个已经存在的交换器或者队列, 只要声明的参数完全匹配现存的交换器或者队列, RabbitMQ就可以什么都不做, 并成功返回, 如果声明的参数不匹配则会抛出异常。

推荐阅读