1、RabbitConfig 类的创建
package com.ovu.config.rabbitMQ;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.*;
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.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Value;
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 java.util.HashMap;
import java.util.Map;
@Configuration
public class RabbitConfig {
@Value("${spring.rabbitmq.host}")
private String host;
@Value("${spring.rabbitmq.port}")
private int port;
@Value("${spring.rabbitmq.username}")
private String username;
@Value("${spring.rabbitmq.password}")
private String password;
@Value("${spring.rabbitmq.virtual-host}")
private String virtual_host;
public static final String EXCHANGE_A = "exchange.a";
public static final String QUEUE_A = "queue.a";
public static final String ROUTINGKEY_A = "routing.key.a";
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(host,port);
connectionFactory.setUsername(username);
connectionFactory.setPassword(password);
connectionFactory.setVirtualHost(virtual_host);
connectionFactory.setPublisherConfirms(true);
Channel channel = connectionFactory.createConnection().createChannel(false);
// 声明queue,exchange,以及绑定
try {
Map<String,Object> args = new HashMap<String,Object>();
args.put("x-delayed-type","direct");
channel.exchangeDeclare(EXCHANGE_A,"x-delayed-message",true,false,args);
//channel.exchangeDeclare(EXCHANGE_A /* exchange名称 */, "direct"/* 类型 */,true);
// durable,exclusive,autodelete
channel.queueDeclare(QUEUE_A, true, false, false, null); // (如果没有就)创建Queue
channel.queueBind(QUEUE_A, EXCHANGE_A, ROUTINGKEY_A);
} catch (Exception e) {
System.out.println("{mq declare queue exchange fail }++++++++++++"+ e);
} finally {
try {
channel.close();
} catch (Exception e) {
System.out.println("mq channel close fail -----------------"+ e);
}
}
return connectionFactory;
}
//注意此下两个bean 有用 有坑时用到
@Bean
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(new Jackson2JsonMessageConverter());
return template;
}
@Bean
public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) {
SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
factory.setConnectionFactory(connectionFactory);
factory.setAcknowledgeMode(AcknowledgeMode.AUTO);
factory.setMessageConverter(new Jackson2JsonMessageConverter());
return factory;
}
/**
* 针对消费者配置
* 1. 设置交换机类型
* 2. 将队列绑定到交换机
FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念
HeadersExchange :通过添加属性key-value匹配
DirectExchange:按照routingkey分发到指定队列
TopicExchange:多关键字匹配
*/
@Bean
public DirectExchange defaultExchange() {
DirectExchange directExchange = new DirectExchange(EXCHANGE_A);
directExchange.setDelayed(true);
return directExchange;
}
/**
* 获取队列
* @return
*/
@Bean
public Queue queue(){
return new Queue(QUEUE_A,true,false,false);
}
/**
* 交换机绑定
* @return
*/
@Bean
public Binding binding(){
return BindingBuilder.bind(queue()).to(defaultExchange()).with(RabbitConfig.ROUTINGKEY_A);
}
}
2、消息发送类
package com.ovu.config.rabbitMQ;
import com.ovu.model.WechatPushRecord;
import com.ovu.service.wechat.push.WechatPushRecordService;
import com.ovu.utils.DateUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class DelayRabbitmqProducer {
@Autowired
private RabbitTemplate rabbitTemplate;
@Autowired
private WechatPushRecordService wechatPushRecordService;
/**
* 发送延时消息
* @param employeeId 员工端id
* @param millisecond
*/
public void sendDelay(String employeeId, Integer millisecond){
WechatPushRecord wechatPushRecord = wechatPushRecordService.query(employeeId);
boolean flag = false;
if (null == wechatPushRecord){
flag = true;
}else {
String time = DateUtils.getTimeByMinute(-30);
time += ":00";
//判断是否已发送
if (wechatPushRecord.getStatus().equals(1) && DateUtils.comparedTwoFullDate(wechatPushRecord.getCreate_time(), time) != 1) {
flag = true;
}
}
if (flag) {
wechatPushRecordService.add(employeeId);
rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_A, RabbitConfig.ROUTINGKEY_A, employeeId, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setHeader("x-delay", millisecond);
return message;
}
});
}
}
}
3、接收者
package com.ovu.config.rabbitMQ;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ovu.entity.wechat.TemplateData;
import com.ovu.entity.wechat.TemplateMessage;
import com.ovu.mapper.SysMessageMapper;
import com.ovu.mapper.TertiaryEstateEmployeeMapper;
import com.ovu.model.TertiaryEstateEmployee;
import com.ovu.model.WechatPushRecord;
import com.ovu.service.wechat.push.WechatPushRecordService;
import com.ovu.utils.DateUtils;
import com.ovu.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
@Component
@Slf4j
public class DelayRabbitmqReceiver {
@Autowired
private TertiaryEstateEmployeeMapper tertiaryEstateEmployeeMapper;
@Autowired
private SysMessageMapper sysMessageMapper;
@Autowired
private WechatPushRecordService wechatPushRecordService;
@Value("${wechat.template_id}")
private String templateId;
@Value("${wechat.app_id}")
private String appId;
@Value("${wechat.app_secret}")
private String appSecret;
@Value("${wechat.url}")
private String url;
@RabbitHandler
@RabbitListener(queues = RabbitConfig.QUEUE_A)//监听指定队列
public void pushWechatMessage(String employeeId){
TertiaryEstateEmployee employee = tertiaryEstateEmployeeMapper.selectByPrimaryKey(employeeId);
Integer count = sysMessageMapper.queryCountByMemberId(employeeId);
String access_token = HttpUtil.sendGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+
appId +"&secret=" + appSecret);
JSONObject jsonObject = JSONObject.parseObject(access_token);
access_token = jsonObject.getString("access_token");
TemplateMessage templateMessage = new TemplateMessage();
templateMessage.setTouser(employee.getOpen_id());
templateMessage.setTemplate_id(templateId);
templateMessage.setUrl(url);
Map<String,TemplateData> map = new HashMap<>();
TemplateData timeData = new TemplateData();
timeData.setValue(DateUtils.getNow());
timeData.setColor("#000000");
map.put("time",timeData);
TemplateData numData = new TemplateData();
numData.setValue(count.toString());
numData.setColor("#000000");
map.put("num",numData);
templateMessage.setData(map);
try {
HttpUtil.sendJsonPost("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" +
access_token, JSON.toJSONString(templateMessage));
wechatPushRecordService.update(employeeId);
}catch (Exception e){
log.error(e.getMessage());
}
}
}
4、对应的类
package com.ovu.entity.wechat;
public class TemplateData {
private String value;
private String color;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
}
package com.ovu.entity.wechat;
import java.util.Map;
public class TemplateMessage {
//用户openid
private String touser;
//模板消息ID
private String template_id;
//详情跳转页面
private String url;
//模板数据封装实体
private Map<String, TemplateData> data;
public String getTouser() {
return touser;
}
public void setTouser(String touser) {
this.touser = touser;
}
public String getTemplate_id() {
return template_id;
}
public void setTemplate_id(String template_id) {
this.template_id = template_id;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map<String, TemplateData> getData() {
return data;
}
public void setData(Map<String, TemplateData> data) {
this.data = data;
}
}
//延时消息需要下载插件rabbitmq_delayed_message_exchange
下载地址:https://bintray.com/rabbitmq/community-plugins/rabbitmq_delayed_message_exchange
安装指令:rabbitmq-plugins enable rabbitmq_delayed_message_exchange