导入jar包
※ rabbitMq各版本与jdk适配不一样, 本文指定适配jdk1.7,所以使用了4.12.0版本。其他JDK请自行适配对应jar包版本
rabbit 4.x 最低适配 jdk1.6
rabbit 5.x 最低适配 jdk1.8
设置spring-rabbit.xml配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/rabbit
http://www.springframework.org/schema/rabbit/spring-rabbit-1.4.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:property-placeholder
ignore-resource-not-found="true"
location="classpath*:/application.properties" />
<!--启用注解监听消息-->
<rabbit:annotation-driven/>
<!-- 配置连接工厂 链接属性从application.properties中取 -->
<rabbit:connection-factory id="connectionFactory"
host="${rabbit.host}"
port="${rabbit.port}"
username="${rabbit.username}"
password="${rabbit.password}"
virtual-host="${rabbit.virtual-host}"/>
<!-- 定义mq管理 -->
<rabbit:admin id="connectAdmin" connection-factory="connectionFactory" auto-startup="true"/>
<!-- 声明消息通知队列 -->
<rabbit:queue name="work.order.queue" durable="true" declared-by="connectAdmin"/>
<!-- 声明延迟消息队列 (死信队列) -->
<rabbit:queue name="work.order.queue.ttl" durable="true" declared-by="connectAdmin">
<rabbit:queue-arguments>
<!-- 绑定交换机和路由 -->
<entry key="x-dead-letter-exchange" value="work.order.direct.ttl" />
<entry key="x-dead-letter-routing-key" value="work.order.topic" />
</rabbit:queue-arguments>
</rabbit:queue>
<!-- 定义交换机 -->
<rabbit:topic-exchange name="work.order.direct" id="work.order.direct">
<rabbit:bindings>
<!-- 绑定队列(通配符模式) #匹配一个或多个词 *匹配一个词 -->
<rabbit:binding queue="work.order.queue" pattern="work.order.topic"/>
</rabbit:bindings>
</rabbit:topic-exchange>
<rabbit:direct-exchange name="work.order.direct.ttl" durable="true">
<rabbit:bindings>
<!-- 绑定延迟消息队列 -->
<rabbit:binding queue="work.order.queue.ttl" key="work.order.topic.ttl" />
<rabbit:binding queue="work.order.queue" key="work.order.topic" />
</rabbit:bindings>
</rabbit:direct-exchange>
<!-- 消息对象json转换类 -->
<bean id="jsonMessageConverter"
class="org.springframework.amqp.support.converter.Jackson2JsonMessageConverter" />
<!-- 定义模版 并设置默认交换机 -->
<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory" message-converter="jsonMessageConverter" exchange="work.order.direct" />
<!-- 定义消费者 -->
<bean name="delayConsumer" class="com.yc.ssm.framwork.mq.WorkOrderListener" />
<!-- 定义消费者监听队列 -->
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener ref="delayConsumer" queues="work.order.queue" />
</rabbit:listener-container>
<!--消息监听容器,配合注解监听消息-->
<bean id="rabbitListenerContainerFactory" class="org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory">
<property name="connectionFactory" ref="connectionFactory"/>
<!--并发消费者数量-->
<property name="concurrentConsumers" value="3"/>
<!--最大数量-->
<property name="maxConcurrentConsumers" value="10"/>
<!--消息转换-->
<property name="messageConverter" ref="jsonMessageConverter"/>
<!--任务线程池-->
<property name="taskExecutor">
<task:executor id="amqpTaskExecutor" pool-size="150"/>
</property>
<!--自动确认-->
<property name="acknowledgeMode" value="AUTO"/>
</bean>
</beans>
消费者监听器
package com.yc.ssm.framwork.mq;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import java.nio.charset.StandardCharsets;
/**
* 延迟队列
* @author xyang
* 2022-04-25 15:02
*/
public class WorkOrderListener implements MessageListener {
@Autowired
RabbitTemplate rabbitTemplate;
@Override
public void onMessage(Message message) {
try {
String body = new String(message.getBody(), StandardCharsets.UTF_8);
System.out.println("[work.order.queue] 队列消息 : " + body);
} catch (Exception e) {
e.printStackTrace();
}
}
}
消息生产者
package com.yc.ssm.framwork.mq;
import com.alibaba.fastjson.JSON;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
import java.util.Date;
/**
* 生产者
* @author xyang
* 2022-04-24 15:50
*/
@Component
public class MqWorkOrderSender {
private final Logger logger = LoggerFactory.getLogger(MqWorkOrderSender.class);
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 将 Java 对象转换为 Amqp Message并将其发送到指定路由键的默认交换器
* @author xyang
* @param routeKey 路由 如:work.order.topic
* @param data 消息对象
* 2022-04-24 15:55
*/
public void send(String routeKey, Object data) {
rabbitTemplate.convertAndSend(routeKey, data);
}
/**
* 发送延迟消息
* @author xyang
* @param exchange 交换机地址 如:work.order.direct.ttl
* @param routeKey 路由 如:work.order.topic.ttl
* @param data 消息对象
* @param delayTime 延迟时间
* 2022-04-24 16:00
*/
public void convertAndSendAtDelay(String exchange, String routeKey, Object data, final long delayTime) {
rabbitTemplate.convertAndSend(exchange, routeKey, data,
new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
//给消息设置延迟毫秒值
message.getMessageProperties().setTimestamp(new Date());
message.getMessageProperties().setExpiration(String.valueOf(delayTime));
return message;
}
});
logger.info("send delay object: {}", JSON.toJSONString(data));
}
}
web.xml 设置扫描spring-rabbit.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:jsp="http://java.sun.com/xml/ns/javaee/jsp" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>cyy</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:/applicationContext*.xml,
classpath*:/spring-*.xml
</param-value>
</context-param>
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>test</param-value>
</context-param>
<filter>
<filter-name>shiroFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetFilterLifecycle</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>shiroFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<session-config>
<session-timeout>60</session-timeout>
</session-config>
<servlet>
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springMvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>captcha</servlet-name>
<servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>captcha</servlet-name>
<url-pattern>/static/captcha.jpg</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>DruidStatView</servlet-name>
<servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DruidStatView</servlet-name>
<url-pattern>/druid/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>default.jsp</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<page-encoding>UTF-8</page-encoding>
<scripting-invalid>false</scripting-invalid>
<trim-directive-whitespaces>true</trim-directive-whitespaces>
</jsp-property-group>
</jsp-config>
</web-app>