http://blog.csdn.net/u011493599/article/details/62892490
引入jar包
[java]?view plain?copy
????
org.springframework.boot????
spring-boot-starter-amqp????
1在resource下創建rabbitmq.properties
[java]?view plain?copy
#是訪問port不是15672,15672是api和管理界面的port??
spring.rabbitmq.addresses=localhost:5672??
spring.rabbitmq.username=admin??
spring.rabbitmq.password=123456??
#如果要進行消息回調,則這里必須要設置為true??
spring.rabbitmq.publisherconfirms=true??
2創建rabbitmq對象RabbitMq
[java]?view plain?copy
package?com.demo.model;??
import?lombok.Getter;??
import?lombok.Setter;??
import?org.springframework.boot.context.properties.ConfigurationProperties;??
import?org.springframework.context.annotation.Configuration;??
/**
?*?Created?by?huguoju?on?2017/3/2.
?*?rabbitmq配置文件
?*/??
@Configuration??
@Getter??
@Setter??
@ConfigurationProperties(locations?=?"classpath:rabbitmq/rabbitmq.properties",prefix?=?"spring.rabbitmq")??
public?class?RabbitMq{??
private?String?addresses;??
private?String?username;??
private?String?password;??
private?Boolean?publisherconfirms;??
}??
3生產者配置
? ?3.1通用性基礎配置
[java]?view plain?copy
package?com.demo.rabbitmq.sender;??
import?com.demo.model.RabbitMq;??
import?lombok.extern.slf4j.Slf4j;??
import?org.springframework.amqp.core.Message;??
import?org.springframework.amqp.core.MessageListener;??
import?org.springframework.amqp.core.Queue;??
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.amqp.rabbit.listener.SimpleMessageListenerContainer;??
import?org.springframework.amqp.rabbit.support.CorrelationData;??
import?org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;??
import?org.springframework.beans.factory.annotation.Autowired;??
import?org.springframework.beans.factory.config.ConfigurableBeanFactory;??
import?org.springframework.context.annotation.Bean;??
import?org.springframework.context.annotation.Configuration;??
import?org.springframework.context.annotation.Scope;??
import?org.springframework.messaging.converter.MappingJackson2MessageConverter;??
/**
?*?Created?by?huguoju?on?2017/3/2.
?*?創建消息生產者
?*/??
@Configuration??
@Slf4j??
public?class?AmqpConfig?{??
@Autowired??
private?RabbitMq?rabbitMq;??
/**
?????*?連接rabbitmq
?????*?@return
?????*/??
@Bean??
public?ConnectionFactory?connectionFactory(){??
CachingConnectionFactory?connectionFactory=new?CachingConnectionFactory();??
????????connectionFactory.setAddresses(rabbitMq.getAddresses());??
????????connectionFactory.setUsername(rabbitMq.getUsername());??
????????connectionFactory.setPassword(rabbitMq.getPassword());??
/**
?????????*?對于每一個RabbitTemplate只支持一個ReturnCallback。
?????????*?對于返回消息,模板的mandatory屬性必須被設定為true,
?????????*?它同樣要求CachingConnectionFactory的publisherReturns屬性被設定為true。
?????????*?如果客戶端通過調用setReturnCallback(ReturnCallback?callback)注冊了RabbitTemplate.ReturnCallback,那么返回將被發送到客戶端。
?????????*?這個回調函數必須實現下列方法:
?????????*void?returnedMessage(Message?message,?intreplyCode,?String?replyText,String?exchange,?String?routingKey);
?????????*/??
//?connectionFactory.setPublisherReturns(true);??
/**
?????????*?同樣一個RabbitTemplate只支持一個ConfirmCallback。
?????????*?對于發布確認,template要求CachingConnectionFactory的publisherConfirms屬性設置為true。
?????????*?如果客戶端通過setConfirmCallback(ConfirmCallback?callback)注冊了RabbitTemplate.ConfirmCallback,那么確認消息將被發送到客戶端。
?????????*?這個回調函數必須實現以下方法:
?????????*?void?confirm(CorrelationData?correlationData,?booleanack);
?????????*/??
????????connectionFactory.setPublisherConfirms(rabbitMq.getPublisherconfirms());??
return?connectionFactory;??
????}??
/**
?????*?rabbitAdmin代理類
?????*?@return
?????*/??
@Bean??
public?RabbitAdmin?rabbitAdmin(ConnectionFactory?connectionFactory){??
return?new?RabbitAdmin(connectionFactory);??
????}??
/**
?????*?創建rabbitTemplate?消息模板類
?????*?prototype原型模式:每次獲取Bean的時候會有一個新的實例
?????*??因為要設置回調類,所以應是prototype類型,如果是singleton類型,則回調類為最后一次設置
?????*?@return
?????*/??
@Bean??
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)??
public?RabbitTemplate?rabbitTemplate(){??
RabbitTemplate?rabbitTemplate=new?RabbitTemplate(connectionFactory());??
//?rabbitTemplate.setMandatory(true);//返回消息必須設置為true??
rabbitTemplate.setMessageConverter(new?Jackson2JsonMessageConverter());//數據轉換為json存入消息隊列??
//??rabbitTemplate.setReplyAddress(replyQueue().getName());??
//??rabbitTemplate.setReplyTimeout(100000000);??
//發布確認??
rabbitTemplate.setConfirmCallback(new?RabbitTemplate.ConfirmCallback()?{??
//消息發送到queue時就執行??
@Override??
public?void?confirm(CorrelationData?correlationData,?boolean?b,?String?s)?{??
log.debug(correlationData+"http://////");??
if?(!b){??
log.debug("發送到queue失敗");??
throw?new?RuntimeException("send?error?"?+?s);??
????????????????}??
????????????}??
????????});??
return?rabbitTemplate;??
????}??
}??
?3.2創建exchange
[java]?view plain?copy
package?com.demo.rabbitmq.sender;??
/**
?*?Created?by?huguoju?on?2017/3/2.
?*?exchange交換機配置
?*/??
public?interface?RabbitMqExchange?{??
final?String?CONTRACT_FANOUT?=?"CONTRACT_FANOUT";??
final?String?CONTRACT_TOPIC?=?"CONTRACT_TOPIC";??
final?String?CONTRACT_DIRECT?=?"CONTRACT_DIRECT";??
}??
3.3創建queue
[java]?view plain?copy
package?com.demo.rabbitmq.sender;??
/**
?*?Created?by?huguoju?on?2017/3/2.
?*?消息隊列配置
?*/??
public?interface?RabbitMqQueue?{??
final?String?CONTRACE_SELF?="CONTRACT_SELF";??
final?String?CONTRACE_TENANT?="CONTRACT_TENANT";??
}??
3.4針對rabbitmq服務性的配置,配置queue和交換機并綁定
[java]?view plain?copy
package?com.demo.rabbitmq.sender;??
import?org.springframework.amqp.core.*;??
import?org.springframework.amqp.rabbit.core.RabbitAdmin;??
import?org.springframework.beans.factory.annotation.Autowired;??
import?org.springframework.beans.factory.annotation.Qualifier;??
import?org.springframework.context.annotation.Bean;??
import?org.springframework.context.annotation.Configuration;??
/**
?*?Created?by?huguoju?on?2017/3/2.
?*?交換機配置并綁定queue
?*/??
@Configuration??
public?class?ContractExchangeConfig?{??
@Autowired??
private?RabbitAdmin?rabbitAdmin;??
/**
?????*?不處理路由鍵。你只需要簡單的將隊列綁定到交換機上。一個發送到交換機的消息都會被轉發到與該交換機綁定的所有隊列上。很像子網廣播,每臺子網內的主機都獲得了一份復制的消息。Fanout交換機轉發消息是最快的。
?????*?@return
?????*/??
//????@Bean??
//????FanoutExchange?contractFanoutExchange(){??
//????????FanoutExchange?fanoutExchange=new?FanoutExchange(RabbitMqExchange.CONTRACT_FANOUT);??
//????????rabbitAdmin.declareExchange(fanoutExchange);??
//????????return?fanoutExchange;??
//????}??
/**
?????*??將路由鍵和某模式進行匹配。此時隊列需要綁定要一個模式上。符號“#”匹配一個或多個詞,符號“*”匹配不多不少一個詞。因此“audit.#”能夠匹配到“audit.irs.corporate”,但是“audit.*”?只會匹配到“audit.irs”
?????*??默認:,?durable?=?true,?autoDelete?=?false
?????*?@return
?????*/??
@Bean??
????TopicExchange?contractTopicExchangeDurable(){??
TopicExchange?contractTopicExchange=new?TopicExchange(RabbitMqExchange.CONTRACT_TOPIC);??
????????rabbitAdmin.declareExchange(contractTopicExchange);??
return?contractTopicExchange;??
????}??
/**
?????*??處理路由鍵。需要將一個隊列綁定到交換機上,要求該消息與一個特定的路由鍵完全匹配。這是一個完整的匹配。如果一個隊列綁定到該交換機上要求路由鍵?“dog”,則只有被標記為“dog”的消息才被轉發,不會轉發dog.puppy,也不會轉發dog.guard,只會轉發dog
?????*?@return
?????*/??
@Bean??
????DirectExchange?contractDirectExchange(){??
DirectExchange?contractDirectExchange=new?DirectExchange(RabbitMqExchange.CONTRACT_DIRECT);??
????????rabbitAdmin.declareExchange(contractDirectExchange);??
return?contractDirectExchange;??
????}??
@Bean??
????Queue?queueContract(){??
Queue?queue=new?Queue(RabbitMqQueue.CONTRACE_SELF,true);??
????????rabbitAdmin.declareQueue(queue);??
return?queue;??
????}??
@Bean??
????Queue?queueTenant(){??
Queue?queue=new?Queue(RabbitMqQueue.CONTRACE_TENANT,true);??
????????rabbitAdmin.declareQueue(queue);??
return?queue;??
????}??
//????@Bean??
//????Binding?bindingExchangeContract(Queue?queueContract,FanoutExchange?exchange){??
//????????Binding?binding=BindingBuilder.bind(queueContract).to(exchange);??
//????????rabbitAdmin.declareBinding(binding);??
//????????return?binding;??
//????}??
@Bean??
????Binding?bindingExchangeContract(Queue?queueContract,TopicExchange?exchange){??
????????Binding?binding=BindingBuilder.bind(queueContract).to(exchange).with(RabbitMqQueue.CONTRACE_SELF);??
????????rabbitAdmin.declareBinding(binding);??
return?binding;??
????}??
//????@Bean??
//????Binding?bindingExchangeContract(Queue?queueContract,DirectExchange?exchange){??
//????????Binding?binding=BindingBuilder.bind(queueContract).to(exchange).with(RabbitMqQueue.CONTRACE_SELF);??
//????????rabbitAdmin.declareBinding(binding);??
//????????return?binding;??
//????}??
@Bean??
????Binding?bindingExchangeTenant(Queue?queueTenant,?TopicExchange?exchange)?{??
????????Binding?binding?=?BindingBuilder.bind(queueTenant).to(exchange).with(RabbitMqQueue.CONTRACE_TENANT);??
????????rabbitAdmin.declareBinding(binding);??
return?binding;??
????}??
//????@Bean??
//????Binding?bindingExchangeTenant(Queue?queueTenant,?DirectExchange?exchange)?{??
//????????Binding?binding?=?BindingBuilder.bind(queueTenant).to(exchange).with(RabbitMqQueue.CONTRACE_TENANT);??
//????????rabbitAdmin.declareBinding(binding);??
//????????return?binding;??
//????}??
}??
3.5創建消息體
[java]?view plain?copy
package?com.demo.rabbitmq.sender;??
import?lombok.Builder;??
import?lombok.Data;??
import?lombok.Getter;??
import?java.util.Date;??
import?java.util.List;??
/**??
*?Created?by?huguoju?on2017/3/3.??
[java]?view plain?copy
?*不能用@Builder,因為json反編譯的時候需要set方法,builder沒有set方法??
?*?合同消息載體??
?*/??
//@Builder??
//@Getter??
@Data??
public?class?ContractRabbitMq?{??
private?String?id;??
private?String?name;??
private?List?testList;??
private?Date?createDate;??
}??
[java]?view plain?copy
package?com.demo.rabbitmq.sender;??
import?lombok.Builder;??
import?lombok.Getter;??
/**
?*?Created?by?huguoju?on?2017/3/3.
?*?tenant消息載體
?*/??
@Builder??
@Getter??
public?class?TenantRabbitMq?{??
private?String?id;??
private?String?name;??
}??
4消費者配置,實際使用時應該和生產者不在一個項目里,這里只是演示,所有放在了一個項目里,很多公用的文件在實際開發中可以打jar用
4.1消息的監聽的代理類
[java]?view plain?copy
package?com.demo.rabbitmq.consumer;??
import?com.demo.model.RabbitMq;??
import?com.demo.rabbitmq.sender.RabbitMqExchange;??
import?com.demo.rabbitmq.sender.RabbitMqQueue;??
import?org.springframework.amqp.core.*;??
import?org.springframework.amqp.rabbit.annotation.EnableRabbit;??
import?org.springframework.amqp.rabbit.annotation.RabbitListenerConfigurer;??
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.listener.RabbitListenerEndpointRegistrar;??
import?org.springframework.beans.factory.annotation.Autowired;??
import?org.springframework.context.annotation.Bean;??
import?org.springframework.context.annotation.Configuration;??
import?org.springframework.messaging.converter.MappingJackson2MessageConverter;??
import?org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory;??
/**
?*?Created?by?huguoju?on?2017/3/3.
?*?接收方配置
?*?消息的監聽的代理類
?*/??
@Configuration??
@EnableRabbit??
public?class?ConsumerConfig?implements?RabbitListenerConfigurer?{??
@Autowired??
????ReceiverService?receiverService;??
@Autowired??
private?RabbitMq?rabbitMq;??
@Autowired??
private?ConnectionFactory?connectionFactory;??
@Bean??
public?DefaultMessageHandlerMethodFactory?handlerMethodFactory(){??
DefaultMessageHandlerMethodFactory?factory=new?DefaultMessageHandlerMethodFactory();??
factory.setMessageConverter(new?MappingJackson2MessageConverter());??
return?factory;??
????}??
//????@Bean??
//????public?SimpleMessageListenerContainer?messageContainer()?{??
//????????SimpleMessageListenerContainer?container?=?new?SimpleMessageListenerContainer(connectionFactory());??
//????????container.setQueues(queueContract());??
//??????//??container.setExposeListenerChannel(true);??
//????????container.setMaxConcurrentConsumers(1);??
//????????container.setConcurrentConsumers(1);??
//????????container.setAcknowledgeMode(AcknowledgeMode.MANUAL);?//設置確認模式手工確認??
//????????container.setMessageListener(new?MessageListener()?{??
//??
//????????????@Override??
//????????????public?void?onMessage(Message?message)?{??
//????????????????byte[]?body?=?message.getBody();??
//????????????????System.out.println("receive?msg?:?"?+?new?String(body));??
//???????????????//?channel.basicAck(message.getMessageProperties().getDeliveryTag(),?false);?//確認消息成功消費??
//????????????}??
//????????});??
//????????return?container;??
//????}??
@Bean??
public?SimpleRabbitListenerContainerFactory?rabbitListenerContainerFactory(){??
SimpleRabbitListenerContainerFactory?factory=new?SimpleRabbitListenerContainerFactory();??
????????factory.setConnectionFactory(connectionFactory);??
????????factory.setAcknowledgeMode(AcknowledgeMode.AUTO);??
return?factory;??
????}??
@Override??
public?void?configureRabbitListeners(RabbitListenerEndpointRegistrar?rabbitListenerEndpointRegistrar)?{??
????????rabbitListenerEndpointRegistrar.setMessageHandlerMethodFactory(handlerMethodFactory());??
????}??
}??
4.2消費者監聽
[java]?view plain?copy
package?com.demo.rabbitmq.consumer;??
import?com.demo.rabbitmq.sender.ContractRabbitMq;??
import?com.demo.rabbitmq.sender.RabbitMqQueue;??
import?com.demo.rabbitmq.sender.TenantRabbitMq;??
import?com.fasterxml.jackson.databind.ObjectMapper;??
import?org.springframework.amqp.rabbit.annotation.RabbitHandler;??
import?org.springframework.amqp.rabbit.annotation.RabbitListener;??
import?org.springframework.stereotype.Component;??
import?java.io.IOException;??
/**
?*?Created?by?huguoju?on?2017/3/3.
?*/??
@Component??
public?class?ReceiverService?{??
@RabbitListener(queues?=?RabbitMqQueue.CONTRACE_SELF)??
@RabbitHandler??
public?void?receiveContractQueue(ContractRabbitMq?contract)?{??
ObjectMapper?objectMapper=new?ObjectMapper();??
try?{??
System.out.println("Received?contract<"?+?objectMapper.writeValueAsString(contract)?+?">");??
}catch?(IOException?e)?{??
????????????e.printStackTrace();??
????????}??
????}??
@RabbitListener(queues?=?RabbitMqQueue.CONTRACE_TENANT)??
public?void?receiveTenantQueue(TenantRabbitMq?tenant)?{??
ObjectMapper?objectMapper=new?ObjectMapper();??
try?{??
System.out.println("Received?contract<"?+?objectMapper.writeValueAsString(tenant)?+?">");??
}catch?(IOException?e)?{??
????????????e.printStackTrace();??
????????}??
????}??
}??
以上就完成了。
創建測試controller
[java]?view plain?copy
package?com.demo.controller;??
import?com.demo.rabbitmq.sender.ContractRabbitMq;??
import?com.demo.service.rabbitMq.ContractRabbitmqService;??
import?com.google.common.collect.Lists;??
import?io.swagger.annotations.Api;??
import?org.springframework.beans.factory.annotation.Autowired;??
import?org.springframework.web.bind.annotation.RequestMapping;??
import?org.springframework.web.bind.annotation.RequestMethod;??
import?org.springframework.web.bind.annotation.RestController;??
import?java.util.Date;??
/**
?*?Created?by?huguoju?on?2017/3/6.
?*/??
@RestController??
@RequestMapping("rabbitmq")??
@Api(value?=?"測試rabbitmq",tags?=?"測試rabbitmq")??
public?class?RabbitMqController?{??
@Autowired??
public?ContractRabbitmqService?contractRabbitmqService;??
@RequestMapping(value?=?"contract/topic",method?=?{RequestMethod.POST,RequestMethod.GET})??
public?void?contractTopic(){??
ContractRabbitMq?mq=new?ContractRabbitMq();??
mq.setId("15");??
mq.setName("測試");??
mq.setTestList(Lists.newArrayList("111","222"));??
mq.setCreateDate(new?Date());??
????????contractRabbitmqService.sendContractRabbitmqTopic(mq);??
????}??
}??