交换器和队列, 在应用程序使用它们的之前就已经存在了, 所以在使用之前要先声明它们
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就可以什么都不做, 并成功返回, 如果声明的参数不匹配则会抛出异常。