rabmitmq整合spring
来源:互联网 发布:网络语鸡肋是什么意思 编辑:程序博客网 时间:2024/06/05 22:44
之前讲了rabmitmq的控制台的相关配置,这些配置是再开发前必要的配置
下面讲讲真货,怎么运用到项目中,本章讲解的是spring整合rabmitmq,废话不多说了,直接上代码
1、首先创建连接池
<bean id="connectionFactory"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<property name="host" value="127.0.0.1" />
<property name="port" value="5672" />
<property name="username" value="test" />
<property name="password" value="test />
<property name="publisherConfirms" value="true" />
<property name="publisherReturns" value="false" />
</bean>
2、创建rabbitTemplate 消息模板类
<bean id="rabbitTemplate" class="org.springframework.amqp.rabbit.core.RabbitTemplate"><constructor-arg ref="connectionFactory"/>
<property name="encoding" value="UTF-8"/>
<property name="channelTransacted" value="false"/>
</bean>
3、定义发送器
<bean id="mqSenderTest" class="com.test.MqSenderTest"> //class指向业务发送器
<property name="rabbitTemplate" ref="rabbitTemplate" />
<property name="queue" value="test.queue" />
<property name="exchange" value="test.queue" />
<property name="routingKey" value="test.queue" />
</bean>
4、定义消费者(如果需要消费消息就配置)
<!--定义queue -->
<rabbit:queue id="queueTest" name="test.queue" durable="true" auto-delete="false" exclusive="false" />
<!-- 定义direct exchange,绑定queue -->
<rabbit:direct-exchange id="exchangeTest" name="test.queue" durable="true" auto-delete="false">
<rabbit:bindings>
<rabbit:binding queue="queueTest" key="test.queue"></rabbit:binding>
</rabbit:bindings>
</rabbit:direct-exchange>
<!-- queue litener 观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象-->
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener queues="queueTest" ref="mqConsumerTest"/>
</rabbit:listener-container>
至此相关的配置就都ok了,接下来是实现定义发送器、消费者
5、每个发送器实现需求可能不同,所以定义抽象发送器,如果发送内容相同则不用定义抽象类,抽象类中的属性都是由上面spring注入的
public abstract class AbstractSenderTest {
protected Logger logger = LoggerFactory.getLogger(getClass());
public String exchange;
public String routingKey;
public String queue;
public RabbitTemplate rabbitTemplate;
public String getExchange() {
return exchange;
}
public void setExchange(String exchange) {
this.exchange = exchange;
}
public String getRoutingKey() {
return routingKey;
}
public void setRoutingKey(String routingKey) {
this.routingKey = routingKey;
}
public String getQueue() {
return queue;
}
public void setQueue(String queue) {
this.queue = queue;
}
public RabbitTemplate getRabbitTemplate() {
return rabbitTemplate;
}
public void setRabbitTemplate(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public abstract void send(MqMessage mqMessage);
}
6、实现发送器抽象类,MqMessage是封装的发送模版,也可以发送json,如果是个类的话接收的时候就需要用这个类来接收了
public class MqSenderTest extends AbstractSenderTest {
public void send(MqMessage mqMessage) {
try {
rabbitTemplate.setQueue(queue);
rabbitTemplate.setExchange(exchange);
rabbitTemplate.setRoutingKey(routingKey);
rabbitTemplate.setChannelTransacted(false);
rabbitTemplate.setImmediate(true);
if (!rabbitTemplate.isConfirmListener()) {
rabbitTemplate.setConfirmCallback(new ConfirmCallback() {
@SuppressWarnings("static-access")
@Override
public void confirm(CorrelationData correlationData, boolean ack) {
if (!ack) {
mqMessage.addSendNum();
if (mqMessage.isAgainSend()) {
rabbitTemplate.convertAndSend(mqMessage);
} else {
logger.error("队列【" + queue + "】MQ消息连续发送" + mqMessage.MAX_SENDNUM + "次失败,报文:"
+ JSONUtils.toJson(mqMessage));
}
}
}
});
}
rabbitTemplate.convertAndSend(mqMessage);
} catch (Exception e) {
logger.error("队列【" + this.queue + "】MQ消息发送失败:" + e);
}
}
}
7、定义抽象消费者,实现MessageListener接口的onMessage方法,只要监听到有接收到消息就开始处理,如果处理失败则重试,fromMessage是处理接收来的消息格式进行相应转换,handle就是实际实现改抽象消费者处理的逻辑
public abstract class AbstractConsumerTest implements MessageListener {
protected final Logger logger = LoggerFactory.getLogger(getClass());
public static final String DEFAULT_CHARSET = "UTF-8";
protected Object fromMessage(Message message) throws MessageConversionException {
Object content = null;
MessageProperties properties = message.getMessageProperties();
if (properties != null) {
String contentType = properties.getContentType();
if (contentType != null && contentType.equals(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)) {
String encoding = properties.getContentEncoding();
if (encoding == null) {
encoding = DEFAULT_CHARSET;
}
try {
content = new String(message.getBody(), encoding);
} catch (UnsupportedEncodingException e) {
logger.error("", e);
throw new MessageConversionException("", e);
}
} else if (contentType != null &&
contentType.equals(MessageProperties.CONTENT_TYPE_SERIALIZED_OBJECT)) {
content = SerializeUtils.deserialize(message.getBody());
}else if (contentType != null &&
contentType.equals(MessageProperties.CONTENT_TYPE_JSON)) {
try {
content = new String(message.getBody(),"utf-8");
} catch (UnsupportedEncodingException e) {
}
}
}
if (content == null) {
content = SerializeUtils.deserialize(message.getBody());
}
return content;
}
@Override
public void onMessage(Message message) {
boolean result = false;
Object object = null;
boolean tranSuccess = true;
try{
object = fromMessage(message);
}catch(Exception e){
logger.error("MQ接收消息转换出错");
tranSuccess = false;
}
if (object == null) {
result = true;
if(tranSuccess){
logger.error("接收到MQ消息 【空】报文");
}
} else if (object instanceof MqMessage) {
try{
MqMessage mqMessage = (MqMessage) object;
logger.error("即将处理的MQ消息:" + JSONUtils.toJson(object));
result = handle(mqMessage);
}catch(Exception e){
result = false;
logger.error("【处理MQ消息异常】"+e);
}
}else if (object instanceof String) {
try{
MqMessage mqMessage = new MqMessage(object);
logger.error("即将处理的MQ(JSON格式)消息:" + object);
result = handle(mqMessage);
}catch(Exception e){
result = false;
logger.error("【处理的MQ(JSON格式)异常:】",e);
}
}
if (!result) {//消息未处理
try {
logger.error("接收后未处理的MQ消息报文:" + JSONUtils.toJson(object));
} catch (Exception e) {
logger.error("接收后未处理的MQ消息报文:" + object);
}
}
}
public abstract boolean handle(MqMessage mqMessage);
}
8、实现抽象消费者,@Service("mqConsumerTest")注册到spring容器中,上面的配置文件有引用这个
@Service("mqConsumerTest")
public class MqConsumerTest extends AbstractConsumerTest {
@Autowired
private MqCloudService mqCloudService;
private Logger logger = LoggerFactory.getLogger(MqCloudConsumer.class);
@Override
public boolean handle(MqMessage mqMessage) {
boolean flag = false;
...具体处理逻辑
return flag;
}
}
9、实现发送mq消息,场景:完成业务发送mq消息记录操作日志
@Service
public class MqLogServiceImpl implements MqLogService {
@Autowired
private MqSenderTest mqSenderTest;
@Override
public void send(){
...
...
...业务逻辑
mqSenderTest.send(new MqMessage());//具体发送什么消息就不写了
}
}
至此spring整合mq的入门阶段就结束了...
- rabmitmq整合spring
- SpringMVC-整合Spring整合
- spring整合
- Spring整合
- Spring -- spring整合struts2
- Spring、整合Spring+JDBC
- Spring:Spring整合Struts2
- Spring:Spring整合Hibernate
- Spring+Spring MVC整合
- Spring-----Spring整合Quartz
- [Spring]Redis+Spring整合
- 【Spring】Spring整合Struts2
- 【Spring】Spring+hibernate整合
- struts整合spring整合hibernate
- spring---整合Junit,整合web
- spring 整合hibernate整合方式
- SSM项目整合-整合Spring
- spring 整合 mybatis,struts2 整合 spring
- 快速幂+快速矩阵幂学习
- Unity3D中的SendMessage使用(消息推送)
- java.util.ConcurrentModificationException:并发修改异常!
- 系统调用和进程切换时的寄存器信息保存在哪里?
- 递归、迭代、到动态规划
- rabmitmq整合spring
- java对象生命周期,以及对象访问。
- 使用mybatis开发步骤
- Kylin+superset可视化
- source insight 4.0中宏定义做为函数返回值时,函数识别错误
- linux驱动由浅入深系列:camera驱动之一(背景及基础知识篇)
- fork/join模式中fork和invokeAll的区别
- 点九图使用
- Tricky Sum