订阅模式中多了一个Exchange交换机,用来接收和处理信息,Exchange有常见三种类型:
Fanout:广播,将消息交给所有绑定到交换机的队列
Direct:定向,把消息交给符合指定routing key 的队列
Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
例子采用的是广播模式。
因为上一篇文章创建连接的代码有过多的重复,因此创建了一个ConnectionUtil工具类。
public class ConnectionUtil {
public static Connection getConnection() throws IOException, TimeoutException {
ConnectionFactory connectionFactory = new ConnectionFactory();
connectionFactory.setHost("192.168.0.110");
connectionFactory.setPort(5672);
connectionFactory.setVirtualHost("/bqsd"); //注意不要漏了/
connectionFactory.setUsername("bqsd");
connectionFactory.setPassword("xj");
Connection connection = connectionFactory.newConnection();
return connection;
}
}
创建生产者:
任务:1、声明交换机 2、声明队列 3、队列需要绑定指定的交换机
public class PublishSubscribeProducer {
public static void main(String[] args) throws IOException, TimeoutException {
//创建连接对象
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
//声明交换机
/** 参数1:交换机名称
* 参数2:交换机类型,fanout、topic、direct、headers
*/
channel.exchangeDeclare("fanout_ex", BuiltinExchangeType.FANOUT);
/**
* 声明队列
* 参数1:队列名称
* 参数2:是否定义持久化队列
* 参数3:是否独占本次连接
* 参数4:是否在不使用的时候自动删除队列
* 参数5:队列其它参数
*/
channel.queueDeclare("q1",true,false,false,null);
channel.queueDeclare("q2",true,false,false,null);
//队列绑定交换机
channel.queueBind("q1","fanout_ex","");
channel.queueBind("q2","fanout_ex","");
//消息
String message = "发布出去啦";
/**
* 参数1:交换机名称,如果没有指定则使用默认Default Exchage
* 参数2:路由key,简单模式可以传递队列名称
* 参数3:消息其它属性
* 参数4:消息内容
*/
channel.basicPublish("fanout_ex","",null,message.getBytes());
channel.close();
connection.close();
}
}
创建两个消费者q1,,q2:
public class PublishSubscribeConsumerOne {
public static void main(String[] args) throws IOException, TimeoutException {
//创建连接对象
Connection connection = ConnectionUtil.getConnection();
Channel channel = connection.createChannel();
/**
* 声明队列
* 参数1:队列名称
* 参数2:是否定义持久化队列
* 参数3:是否独占本次连接
* 参数4:是否在不使用的时候自动删除队列
* 参数5:队列其它参数
*/
channel.queueDeclare("q1",true,false,false,null);
//创建消费者,并设置消息处理
DefaultConsumer defaultConsumer = new DefaultConsumer(channel) {
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
//路由key
System.out.println("路由key为:" + envelope.getRoutingKey());
//交换机
System.out.println("交换机为:" + envelope.getExchange());
//消息id
System.out.println("消息id为:" + envelope.getDeliveryTag());
//收到的消息
System.out.println("消费者One-接收到的消息为:" + new String(body, "utf-8"));
}
};
//消息监听
channel.basicConsume("q1",true,defaultConsumer);
//关闭资源
// channel.close();
// connection.close();
}
}
(q2就不重复发了)
打开两个消费者等待接收信息,再打开生产者,即可看到广播效果
打开RabbitMQ管理页面,点击Exchange页面,打开自己定义的交换机,即可看到绑定效果
Ok!