一、pom文件
<dependency> <groupId>org.springframework.amqp</groupId> <artifactId>spring-rabbit</artifactId> <version>1.7.0.RELEASE</version> </dependency>
二、Rabbitmq配置文件
package config; import org.springframework.amqp.core.AmqpAdmin; import org.springframework.amqp.rabbit.annotation.EnableRabbit; import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.core.RabbitAdmin; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //连接rabbitMQ的基本配置 @Configuration @EnableRabbit public class RabbitConfig { @Bean public ConnectionFactory connectionFactory() { CachingConnectionFactory connectionFactory = new CachingConnectionFactory("192.168.0.102"); connectionFactory.setUsername("xxxx"); connectionFactory.setPassword("xxxx"); connectionFactory.setPort(5672); return connectionFactory; } @Bean public AmqpAdmin amqpAdmin() { return new RabbitAdmin(connectionFactory()); } @Bean public RabbitTemplate rabbitTemplate() { return new RabbitTemplate(connectionFactory()); } //配置消费者监听的容器 @Bean public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory() { SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); factory.setConnectionFactory(connectionFactory()); factory.setConcurrentConsumers(3); factory.setMaxConcurrentConsumers(10); return factory; } }
三、消息模型
1)生产者消费者模型
如上图,生产者消费者模型:添加了一个队列,并创建了两个消费者用于监听队列消息,我们发现,当有消息到达时,两个消费者会交替收到消息。这一过程虽然不用创建交换机,但会使用默认的交换机,并用默认的直连(default-direct)策略连接队列;
生产者:
package service.impl; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import po.Mail; import service.Producer; @Transactional @Service("producer") public class ProducerImpl implements Producer{ @Autowired RabbitTemplate rabbitTemplate; public void sendMail(String queue,Mail mail) { rabbitTemplate.setQueue("myqueue"); rabbitTemplate.convertAndSend("myqueue",mail); } }
消费者:
package rabbitMQ.listener; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; import po.Mail; @Component public class QueueListener1 { @RabbitListener(queues = "myqueue") public void displayMail(Mail mail) throws Exception { System.out.println("队列监听器1号收到消息"+mail.toString()); } }
配置文件:
package config; import org.springframework.amqp.core.Queue; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //生产者消费者模式的配置,包括一个队列和两个对应的消费者 @Configuration public class ProducerConsumerConfig { @Autowired RabbitConfig rabbitconfig; @Bean public Queue myQueue() { Queue queue=new Queue("myqueue"); return queue; } }
2)消息订阅模型
如图,发布订阅模型,添加两个队列,分别各用一个消费者监听,设置一个交换机,类型为广播(fanout),交换机会将收到的消息广播给所有相连的队列
配置文件:
package config; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.Queue; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //发布订阅模式的配置,包括两个队列和对应的订阅者,发布者的交换机类型使用fanout(子网广播),两根网线binding用来绑定队列到交换机 @Configuration public class PublishSubscribeConfig { @Autowired RabbitConfig rabbitconfig; @Bean public Queue myQueue1() { Queue queue=new Queue("queue1"); return queue; } @Bean public Queue myQueue2() { Queue queue=new Queue("queue2"); return queue; } @Bean public FanoutExchange fanoutExchange(){ FanoutExchange fanoutExchange=new FanoutExchange("fanout"); return fanoutExchange; } @Bean public Binding binding1(){ Binding binding=BindingBuilder.bind(myQueue1()).to(fanoutExchange()); return binding; } @Bean public Binding binding2(){ Binding binding=BindingBuilder.bind(myQueue2()).to(fanoutExchange()); return binding; } }
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import po.Mail; import service.Publisher; @Service("publisher") public class PublisherImpl implements Publisher{ @Autowired RabbitTemplate rabbitTemplate; public void publishMail(Mail mail) { rabbitTemplate.convertAndSend("fanout", "", mail); } }
package rabbitMQ.listener; import java.io.IOException; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; import po.Mail; @Component public class SubscribeListener1 { @RabbitListener(queues = "queue1") public void subscribe(Mail mail) throws IOException { System.out.println("订阅者1收到消息"+mail.toString()); } }
3)直连交换机通信模型
包括一个direct交换机,三个binding,两个队列,两个消费者监听器,消息只会被投入到routingkey一致的队列中。
配置文件:
package config; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.DirectExchange; import org.springframework.amqp.core.Queue; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //direct直连模式的交换机配置,包括一个direct交换机,两个队列,三根网线binding @Configuration public class DirectExchangeConfig { @Bean public DirectExchange directExchange(){ DirectExchange directExchange=new DirectExchange("direct"); return directExchange; } @Bean public Queue directQueue1() { Queue queue=new Queue("directqueue1"); return queue; } @Bean public Queue directQueue2() { Queue queue=new Queue("directqueue2"); return queue; } //3个binding将交换机和相应队列连起来 @Bean public Binding bindingorange(){ Binding binding=BindingBuilder.bind(directQueue1()).to(directExchange()).with("orange"); return binding; } @Bean public Binding bindingblack(){ Binding binding=BindingBuilder.bind(directQueue2()).to(directExchange()).with("black"); return binding; } @Bean public Binding bindinggreen(){ Binding binding=BindingBuilder.bind(directQueue2()).to(directExchange()).with("green"); return binding; } }
发送者:
package service.impl; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import po.Mail; import service.Publisher; @Service("publisher") public class PublisherImpl implements Publisher{ @Autowired RabbitTemplate rabbitTemplate; public void senddirectMail(Mail mail, String routingkey) { rabbitTemplate.convertAndSend("direct", routingkey, mail); } }
接收者:
package rabbitMQ.listener; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; import po.Mail; @Component public class DirectListener1 { @RabbitListener(queues = "directqueue1") public void displayMail(Mail mail) throws Exception { System.out.println("directqueue1队列监听器1号收到消息"+mail.toString()); } }
4)主题交换机通信模型
包括一个topic交换机,三个binding,两个队列,两个消费者监听器,消息只会被投入到routingkey能够匹配的队列中,#表示0个或若干个关键字,*表示一个关键字
配置文件:
package config; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.TopicExchange; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //topic交换机模型,需要一个topic交换机,两个队列和三个binding @Configuration public class TopicExchangeConfig { @Bean public TopicExchange topicExchange(){ TopicExchange topicExchange=new TopicExchange("mytopic"); return topicExchange; } @Bean public Queue topicQueue1() { Queue queue=new Queue("topicqueue1"); return queue; } @Bean public Queue topicQueue2() { Queue queue=new Queue("topicqueue2"); return queue; } //3个binding将交换机和相应队列连起来 @Bean public Binding bindingtopic1(){ Binding binding=BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("*.orange.*");//binding key return binding; } @Bean public Binding bindingtopic2(){ Binding binding=BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("*.*.rabbit"); return binding; } @Bean public Binding bindingtopic3(){ Binding binding=BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("lazy.#");//#表示0个或若干个关键字,*表示一个关键字 return binding; } }
发送者:
package service.impl; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import po.Mail; import service.Publisher; @Service("publisher") public class PublisherImpl implements Publisher{ @Autowired RabbitTemplate rabbitTemplate; public void sendtopicMail(Mail mail, String routingkey) { rabbitTemplate.convertAndSend("mytopic", routingkey, mail); } }
接收者:
package rabbitMQ.listener; import java.io.IOException; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import po.Mail; @Component public class TopicListener1 { @RabbitListener(queues = "topicqueue1") public void displayTopic(Mail mail) throws IOException { System.out.println("从topicqueue1取出消息"+mail.toString()); } }