springboot集成activeMQ
1、依赖
<!-- activemq -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
<!-- 开启连接池需要引入该依赖-->
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
</dependency>
2、.application.properties中加入activemq的配置
spring.activemq.broker-url=tcp://localhost:61616
spring.activemq.user=admin
spring.activemq.password=admin
spring.activemq.pool.enabled=false
spring.jms.pub-sub-domain=true
spring.activemq.packages.trust-all=true
配置说明
spring.activemq.packages.trust-all=true //表示新任所有的实体类 最新的版本添加安全机制,只有信任的实体类才能传输
spring.activemq.packages.trusted=com.example.model //指定信任的实体类包、
spring.activemq.pool.enabled=false //连接池开关 开启需要导入上面的连接池依赖
3、activeMQ 简介
- Domains:消息传递方式,包括点对点(P2P)、发布/订阅(Pub/Sub)两种
- Connection factory:客户端使用连接工厂来创建与 JMS provider 的连接
- Destination:消息被寻址、发送以及接收的对象
P2P (点对点)消息域使用 queue 作为 Destination,消息可以被同步或异步的发送和接收,每个消息只会给一个 Consumer 传送一次。
Consumer 可以使用 MessageConsumer.receive() 同步地接收消息,也可以通过使用MessageConsumer.setMessageListener() 注册一个 MessageListener 实现异步接收。
4、实例(这里只演示实体类的传输)
新建实体类(*实体类必须实现序列化)
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
新建一个JMS的配置类
这里是为了同时支持发送和接收queue/topic
package com.example.config;
import javax.jms.ConnectionFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.stereotype.Component;
@Component
public class MyJMSFactory {
// topic模式的ListenerContainer
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) {
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setPubSubDomain(true);
bean.setConnectionFactory(activeMQConnectionFactory);
return bean;
}
// queue模式的ListenerContainer
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerQueue(ConnectionFactory activeMQConnectionFactory) {
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setConnectionFactory(activeMQConnectionFactory);
return bean;
}
}
5、queue的发送和接收
创建两个springboot项目一个是生产者 一个作为消费者
生产者项目创建生产者类
@Service
public class Producer {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
public void sendMsg(String destinationName, Object message) {
System.out.println("============发送消息" + message);
Destination destination = new ActiveMQQueue(destinationName);
jmsMessagingTemplate.convertAndSend(destination, message);
}
}
消费者项目创建消费者
@Service
public class Consumer {
@JmsListener(destination = "test.queue", containerFactory = "jmsListenerContainerQueue")
public void receiveMsg(ActiveMQObjectMessage msg) throws JMSException {
System.out.println("接收消息:" + msg.getObject());
}
}
生产者发送数据
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProducerTests {
@Autowired
private Producer prodecer;
@Test
public void contextLoads() {
for(int i = 0; i < 10;i++) {
User user = new User();
user.setAge(i);
user.setName("queue消息" + i);
prodecer.sendMsg("test.queue", user);
}
}
}
测试结果
消费者支持多个消费者,但是一个消息只会被一个消费者接收,采用轮询算法轮流接收,当没有消费者是消息暂时被存入内存队列中,直到有消费者消费
6、topic模式的发送和接收
发布/订阅模式 消费者提前订阅消息,生产者发消息时 所有的消费者都能收到订阅的所有消息
创建一个生产者/发布者
@Service
public class Pulisher {
@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;
public void publish(String destinationName, Object msg) {
Destination destination = new ActiveMQTopic(destinationName);
System.out.println("=======发布消息:" + msg);
jmsMessagingTemplate.convertAndSend(destination, msg);
}
}
创建一个订阅者/消费者
@Service
public class Subscriber {
@JmsListener(destination = "test.topic", containerFactory = "jmsListenerContainerTopic")
public void sunscriber(ActiveMQObjectMessage msg) {
try {
System.out.println("接受订阅消息: " +msg.getObject());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
必须先启动订阅者,再进行发布消息
public class PublishTests {
@Autowired
private Pulisher pulisher;
@Test
public void contextLoads() {
for(int i = 0; i < 10;i++) {
User user = new User();
user.setAge(i);
user.setName("topic消息" + i);
pulisher.publish("test.topic", user);
}
}
}