RabbitMQ:RabbitMQ+Sping整合发送异步消息
(一) XML配置方式:
1.【配置文件】:
application-async.xml
#============== rabbitmq config ====================
rabbit.hosts=127.0.0.1
rabbit.username=
rabbit.password=
rabbit.virtualHost=/
rabbit.queue=spring-queue-async
rabbit.routingKey=spring-queue-async
消费者配置XML :applicationContext-rabbitmq-async-receive.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<!-- 标准配置 -->
<value>classpath*:/application-async.properties</value>
</list>
</property>
</bean>
<!-- 创建connectionFactory -->
<bean id="rabbitConnectionFactory"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<constructor-arg value="${rabbit.hosts}"/>
<property name="username" value="${rabbit.username}"/>
<property name="password" value="${rabbit.password}"/>
<property name="virtualHost" value="${rabbit.virtualHost}"/>
<property name="channelCacheSize" value="5"/>
</bean>
<!-- 声明消息转换器为SimpleMessageConverter -->
<bean id="messageConverter"
class="org.springframework.amqp.support.converter.SimpleMessageConverter">
</bean>
<!-- 监听生产者发送的消息开始 -->
<!-- 用于接收消息的处理类 -->
<bean id="receiveHandler"
class="com.caox.rabbitmq.demo._09_spring_rabbitmq_async_xml.ReceiveMsgHandler">
</bean>
<!-- 用于消息的监听的代理类MessageListenerAdapter -->
<bean id="receiveListenerAdapter"
class="org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter">
<constructor-arg ref="receiveHandler" />
<property name="defaultListenerMethod" value="handleMessage"></property>
<property name="messageConverter" ref="messageConverter"></property>
</bean>
<!-- 用于消息的监听的容器类SimpleMessageListenerContainer,对于queueName的值一定要与定义的Queue的值相同 -->
<bean id="listenerContainer"
class="org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer">
<property name="queueNames" value="${rabbit.queue}"></property>
<property name="connectionFactory" ref="rabbitConnectionFactory"></property>
<property name="messageListener" ref="receiveListenerAdapter"></property>
</bean>
<!-- 监听生产者发送的消息结束 -->
</beans>
生产者XML配置:applicationContext-rabbitmq-async-send.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" />
<property name="ignoreResourceNotFound" value="true" />
<property name="locations">
<list>
<!-- 标准配置 -->
<value>classpath*:/application-async.properties</value>
</list>
</property>
</bean>
<!-- 创建connectionFactory -->
<bean id="rabbitConnectionFactory"
class="org.springframework.amqp.rabbit.connection.CachingConnectionFactory">
<constructor-arg value="${rabbit.hosts}"/>
<property name="username" value="${rabbit.username}"/>
<property name="password" value="${rabbit.password}"/>
<property name="virtualHost" value="${rabbit.virtualHost}"/>
<property name="channelCacheSize" value="5"/>
</bean>
<!-- 创建rabbitAdmin 代理类 -->
<bean id="rabbitAdmin"
class="org.springframework.amqp.rabbit.core.RabbitAdmin">
<constructor-arg ref="rabbitConnectionFactory" />
</bean>
<!-- 创建rabbitTemplate 消息模板类
-->
<bean id="rabbitTemplate"
class="org.springframework.amqp.rabbit.core.RabbitTemplate">
<constructor-arg ref="rabbitConnectionFactory"></constructor-arg>
<property name="routingKey" value="${rabbit.routingKey}"></property>
</bean>
</beans>
接收消息启动类:Receive.java 启动接收消息,再发送消息
package com.caox.rabbitmq.demo._09_spring_rabbitmq_async_xml;
/**
* Created by nazi on 2018/7/27.
*/
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Receive {
public static void main(String[] args) {
new ClassPathXmlApplicationContext("applicationContext-rabbitmq-async-receive.xml");
}
}
生产者发送消息类:Send.java
package com.caox.rabbitmq.demo._09_spring_rabbitmq_async_xml;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by nazi on 2018/7/27.
*/
public class Send {
public static void main(String[] args) throws InterruptedException {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-rabbitmq-async-send.xml");
AmqpTemplate amqpTemplate = context.getBean(RabbitTemplate.class);
for(int i=0;i<1000;i++){
amqpTemplate.convertAndSend("test spring async=>"+i);
Thread.sleep(3000);
}
}
}
处理消息类:ReceiveMsgHandler.java
package com.caox.rabbitmq.demo._09_spring_rabbitmq_async_xml;
/**
* Created by nazi on 2018/7/27.
*/
public class ReceiveMsgHandler {
public void handleMessage(String text) {
System.out.println("Received: " + text);
}
}
(二) Annotation 注解方式:
1.【生产者配置和启动类】:ProducerConfiguration.java 和 Producer.java
package com.caox.rabbitmq.demo._10_spring_rabbitmq_async_annotation;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
import com.rabbitmq.client.AMQP;
/**
* Created by nazi on 2018/7/27.
*/
@Configuration
public class ProducerConfiguration {
// 指定队列名称 routingkey的名称默认为Queue的名称,使用Exchange类型为DirectExchange
protected final String helloWorldQueueName = "spring-queue-async";
// 创建链接
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory("127.0.0.1");
connectionFactory.setUsername("caoxia");
connectionFactory.setPassword("caoxia123456");
connectionFactory.setPort(AMQP.PROTOCOL.PORT);
return connectionFactory;
}
// 创建rabbitTemplate 消息模板类
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
template.setRoutingKey(this.helloWorldQueueName);
return template;
}
//创建一个调度
@Bean
public ScheduledProducer scheduledProducer() {
return new ScheduledProducer();
}
@Bean
public BeanPostProcessor postProcessor() {
return new ScheduledAnnotationBeanPostProcessor();
}
static class ScheduledProducer {
@Autowired
private volatile RabbitTemplate rabbitTemplate;
//自增整数
private final AtomicInteger counter = new AtomicInteger();
/**
* 每3秒发送一条消息
*
* Spring3中加强了注解的使用,其中计划任务也得到了增强,现在创建一个计划任务只需要两步就完成了:
创建一个Java类,添加一个无参无返回值的方法,在方法上用@Scheduled注解修饰一下;
在Spring配置文件中添加三个<task:**** />节点;
参考:http://zywang.iteye.com/blog/949123
*/
@Scheduled(fixedRate = 3000)
public void sendMessage() {
rabbitTemplate.convertAndSend("Hello World " + counter.incrementAndGet());
}
}
}
package com.caox.rabbitmq.demo._10_spring_rabbitmq_async_annotation;
/**
* Created by nazi on 2018/7/27.
*/
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Producer {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(ProducerConfiguration.class);
}
}
2.【消费者配置和启动类】: ConsumerConfiguration.java和Consumer.java
package com.caox.rabbitmq.demo._10_spring_rabbitmq_async_annotation;
import org.springframework.amqp.core.AmqpAdmin;
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.listener.adapter.MessageListenerAdapter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.rabbitmq.client.AMQP;
/**
* Created by nazi on 2018/7/27.
*/
@Configuration
public class ConsumerConfiguration {
// 指定队列名称 routingkey的名称默认为Queue的名称,使用Exchange类型为DirectExchange
protected String springQueueDemo = "spring-queue-async";
// 创建链接
@Bean
public ConnectionFactory connectionFactory() {
CachingConnectionFactory connectionFactory = new CachingConnectionFactory(
"127.0.0.1");
connectionFactory.setUsername("caoxia");
connectionFactory.setPassword("caoxia123456");
connectionFactory.setPort(AMQP.PROTOCOL.PORT);
return connectionFactory;
}
// 创建rabbitAdmin 代理类
@Bean
public AmqpAdmin amqpAdmin() {
return new RabbitAdmin(connectionFactory());
}
// 创建rabbitTemplate 消息模板类
@Bean
public RabbitTemplate rabbitTemplate() {
RabbitTemplate template = new RabbitTemplate(connectionFactory());
// The routing key is set to the name of the queue by the broker for the
// default exchange.
template.setRoutingKey(this.springQueueDemo);
// Where we will synchronously receive messages from
template.setQueue(this.springQueueDemo);
return template;
}
//
// Every queue is bound to the default direct exchange
public Queue helloWorldQueue() {
return new Queue(this.springQueueDemo);
}
@Bean
public SimpleMessageListenerContainer listenerContainer() {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory());
container.setQueueNames(this.springQueueDemo);
container.setMessageListener(new MessageListenerAdapter(
new ReceiveMsgHandler()));
return container;
}
}
package com.caox.rabbitmq.demo._10_spring_rabbitmq_async_annotation;
/**
* Created by nazi on 2018/7/27.
*/
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Consumer {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(ConsumerConfiguration.class);
}
}
3.【接收消息处理类 】:ReceiveMsgHandler.java
package com.caox.rabbitmq.demo._10_spring_rabbitmq_async_annotation;
/**
* Created by nazi on 2018/7/27.
*/
public class ReceiveMsgHandler {
public void handleMessage(String text) {
System.out.println("Received: " + text);
}
}