springamqp是利用spring核心技术实现访问基于AMQP协议的消息服务器的解决方案,是spring的一个子项目,他并不是一个具体的实现,而是提供了高级接口,具体实现springamqp的项目有spring-rabbit,这里介绍如何整合springamqp、rabbitmq。
构建maven项目,引入spring-rabbit依赖。
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit</artifactId>
<version>2.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
纯java实现,无需spring配置文件:
自定义消息接收监听器 MyRabbitMessageListener.java
package com.xxx.springamqp.listener;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageListener;
import org.springframework.stereotype.Component;
@Component
public class MyRabbitMessageListener implements MessageListener {
@Override
public void onMessage(Message message) {
String body = new String(message.getBody());
System.out.println("server receive message : "+body);
}
}
RabbitMQStarter.java启动类
package com.xxx.springamqp;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.TopicExchange;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import com.xxx.springamqp.listener.MyRabbitMessageListener;
public class RabbitMQStarter {
public static void main(String[] args) {
try {
CachingConnectionFactory factory = new CachingConnectionFactory("10.119.9.149", 5672);
factory.setUsername("admin");
factory.setPassword("admin");
RabbitAdmin admin = new RabbitAdmin(factory);
Queue queue = new Queue("queue");
admin.declareQueue(queue);
TopicExchange exchange = new TopicExchange("myExchange");
admin.declareExchange(exchange);
admin.declareBinding(BindingBuilder.bind(queue).to(exchange).with("rabbit.*"));
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer(factory);
container.setMessageListener(new MyRabbitMessageListener());
container.setQueueNames("queue");
container.start();
RabbitTemplate template = new RabbitTemplate(factory);
template.convertAndSend("myExchange", "rabbit.mq", "hello,rabbitmq");
Thread.sleep(2000);
container.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行,控制台打印信息:
[INFO ] 2018-09-10 16:32:40 org.springframework.amqp.rabbit.connection.CachingConnectionFactory Attempting to connect to: 10.119.9.149:5672
[INFO ] 2018-09-10 16:32:40 org.springframework.amqp.rabbit.connection.CachingConnectionFactory Created new connection: SpringAMQP#68837a77:0/SimpleConnection@5d5eef3d [delegate=amqp://admin@10.119.9.149:5672/, localPort= 51687]
server receive message : hello,rabbitmq
这种方式实现中,连接rabbitmq时,需要配置username,password,否则会出现如下所示的错误:
org.springframework.amqp.AmqpAuthenticationException: com.rabbitmq.client.AuthenticationFailureException: ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.
at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:65)
at org.springframework.amqp.rabbit.connection.AbstractConnectionFactory.createBareConnection(AbstractConnectionFactory.java:484)
at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:626)
at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:240)
at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:1797)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1771)
at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:1752)
at org.springframework.amqp.rabbit.core.RabbitAdmin.declareQueue(RabbitAdmin.java:240)
at com.xxx.springamqp.RabbitMQStarter.main(RabbitMQStarter.java:18)
利用spring配置文件实现:
<?xml version="1.0" encoding="UTF-8"?>
<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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit-2.0.xsd">
<context:component-scan base-package="com.xxx.springamqp"/>
<rabbit:connection-factory id="connectionFactory" host="10.119.9.149" port="5672"
username="admin" password="admin" virtual-host="/" requested-heartbeat="60"/>
<rabbit:template id="rabbitTemplate" connection-factory="connectionFactory" exchange="myExchange"/>
<rabbit:topic-exchange name="myExchange">
<rabbit:bindings>
<rabbit:binding queue="queue" pattern="rabbit.*"/>
</rabbit:bindings>
</rabbit:topic-exchange>
<rabbit:queue name="queue" />
<rabbit:admin connection-factory="connectionFactory"/>
<rabbit:listener-container connection-factory="connectionFactory">
<rabbit:listener ref="myRabbitMessageListener" queue-names="queue"/>
</rabbit:listener-container>
</beans>
启动类 RabbitMQApp.java:
package com.xxx.springamqp;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class RabbitMQApp {
@SuppressWarnings({ "resource" })
public static void main( String[] args ){
try {
AbstractApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-rabbit.xml");
RabbitTemplate template = context.getBean(RabbitTemplate.class);
template.convertAndSend("myExchange","rabbit.mq","hello,rabbit");
Thread.sleep(2000);
context.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行之后,控制台打印信息:
[INFO ] 2018-09-10 16:36:00 org.springframework.context.support.ClassPathXmlApplicationContext Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2db0f6b2: startup date [Mon Sep 10 16:36:00 CST 2018]; root of context hierarchy
[INFO ] 2018-09-10 16:36:00 org.springframework.beans.factory.xml.XmlBeanDefinitionReader Loading XML bean definitions from class path resource [spring-rabbit.xml]
[INFO ] 2018-09-10 16:36:01 org.springframework.context.support.DefaultLifecycleProcessor Starting beans in phase 2147483647
[INFO ] 2018-09-10 16:36:01 org.springframework.amqp.rabbit.connection.CachingConnectionFactory Attempting to connect to: 10.119.9.149:5672
[INFO ] 2018-09-10 16:36:01 org.springframework.amqp.rabbit.connection.CachingConnectionFactory Created new connection: connectionFactory#3d74bf60:0/SimpleConnection@400f1450 [delegate=amqp://admin@10.119.9.149:5672/, localPort= 52062]
server receive message : hello,rabbit
两种方式实现,均需要配置admin用户的权限,如果不配置,会报如下错误:
Caused by: com.rabbitmq.client.ShutdownSignalException: connection error; protocol method: #method<connection.close>(reply-code=530, reply-text=NOT_ALLOWED - access to vhost '/' refused for user 'admin', class-id=10, method-id=40)
at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66)
at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36)
at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:494)
at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:288)
at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:138)
... 14 more
配置权限的方法如下:
[root@server ~]# rabbitmqctl set_permissions -p / admin '.*' '.*' '.*'
Setting permissions for user "admin" in vhost "/"