队列配置、生产者配置、消费者配置和一般的mq配置相同。
reply-timeout是过期时间,可以写到配置文件中。
<rabbit:template id="template" message-converter="messageConverter"
connection-factory="connectionFactory" reply-timeout="2000" retry-template="retryTemplate"
exchange="${rabbitmq.direct.exchange}" />
1.生产者代码示例
使用template.convertSendAndReceive方法即为RPC调用,本例中使用了direct模式,也可以使用fanout和topic。
public class MqBlocking extends BaseTask {
@Override
protected void execute(final ScheduleJob scheduleJob, final String id) {
RabbitTemplate template = (RabbitTemplate) SpringContextHolder.getBean("template");
BaseResponse obj = (BaseResponse) template.convertSendAndReceive(template.getExchange(), "ccs.binding." + scheduleJob.getMqName(), id, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setHeader("jobName", scheduleJob.getName());
return message;
}
});
}
}
2.消费者代码示例
@RabbitListener(queues = "ccs.queue.blocking")
public BaseResponse helloBlocking(String id, @Header("jobName") String jobName) {
System.out.println("Received request for id " + id);
System.out.println("Received request for job name " + jobName);
//返回执行结果(成功,失败)和ID
BaseResponse response = new BaseResponse(true, id);
return response;
}
3.代码实现方式
因为低版本的mq不支持注解,只能使用代码来配置监听器
消费者配置
<!-- 消息转换器 -->
<bean id="messageConverter" class="org.springframework.amqp.support.converter.JsonMessageConverter" />
<!-- 队列配置 -->
<rabbit:queue name="ccs.queue.blocking" />
<rabbit:direct-exchange name="ccs.direct.exchange">
<rabbit:bindings>
<rabbit:binding queue="ccs.queue.blocking" key="ccs.binding.blocking" />
</rabbit:bindings>
</rabbit:direct-exchange>
<!-- 监听器配置 -->
<rabbit:listener-container connection-factory="connectionFactory" message-converter="jsonMessageConverter">
<rabbit:listener ref="queueHandler" method="handle" queues="ccs.queue.blocking" />
</rabbit:listener-container>
消费者代码
package com.whty.bwjf.tsp.cm.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.whty.bwjf.framework.core.util.JsonMessageConverter;
import com.whty.framework.base.web.mvc.view.BaseResponse;
@Component
public class QueueHandler {
@Autowired
private JsonMessageConverter messageConverter;
Logger logger = LoggerFactory.getLogger(QueueHandler.class);
public Message handle(Message message)
{
System.out.println("Received request for jobname " + message.getMessageProperties().getHeaders().get("jobName"));
String id = (String) messageConverter.fromMessage(message);
System.out.println("Received request for id " + id);
//返回执行结果(成功,失败)和ID
BaseResponse response = new BaseResponse(true, id);
return messageConverter.toMessage(response, new MessageProperties());
}
}
PS:有可能在第一次加上这些配置的时候,消息会先经过Converter,但是Converter中转换为实体类型后,就无法进入到handle中。
可以配置一个空转换器来解决此问题
package com.whty.bwjf.framework.core.util;
import java.io.UnsupportedEncodingException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.support.converter.AbstractMessageConverter;
import org.springframework.amqp.support.converter.MessageConversionException;
import com.alibaba.fastjson.JSON;
@Component
public class OriginMessageConverter extends AbstractMessageConverter {
public OriginMessageConverter() {
super();
}
public void setDefaultCharset(String defaultCharset) {
this.defaultCharset = (defaultCharset != null) ? defaultCharset
: DEFAULT_CHARSET;
}
public Object fromMessage(Message message)
throws MessageConversionException {
return message;
}
protected Message createMessage(Object objectToConvert,
MessageProperties messageProperties)
throws MessageConversionException {
return (Message) objectToConvert;
}
}
<rabbit:listener-container connection-factory="connectionFactory" message-converter="originMessageConverter">
<rabbit:listener ref="queueHandler" method="handle" queues="crm.hb.queue" />
</rabbit:listener-container>