交換器和隊列, 在應用程序使用它們的之前就已經存在了, 所以在使用之前要先聲明它們
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就可以什么都不做, 並成功返回, 如果聲明的參數不匹配則會拋出異常。