1、导入依赖
导入activeMQ的依赖(使用springboot,创建应用时,直接可选)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-activemq</artifactId>
</dependency>
如果需要使用池(pool)则需要导入依赖
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-pool</artifactId>
<version>5.15.9</version>
</dependency>
导入依赖后,需要在配置文件中开启池的使用:
spring.activemq.pool.enable=true
spring.activemq.pool.max-connections=10(根据业务定义)
2、开始配置activemq的
application.yml配置文件如下:
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/blog?useUnicode=true&characterEncoding=UTF-8
username: root
password: 12345678
#消息队列配置
activemq:
user: admin
password: admin
broker-url: tcp://192.168.65.130:61616 #注:这里的端口不是8161
pool: #这里开启连接池,默认是不开启的
enabled: true
max-connections: 10
# jms:
# pub-sub-domain: true #如果设置为true,则说明是 订阅模式,则queue模式无法接收到消息了,
#这里也可以不做配置,直接在ActiveMQConfig中配置,设置setPubSubDomain为true即可
queueName: publish.queue #这是自定义的队列名称
topicName: publish.topic1 #这是自定义的主题名称
消息队列的配置java文件:
import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import javax.jms.Queue;
import javax.jms.Topic;
/**
* 消息队列配置文件
*/
@Configuration
public class ActiveMQConfig {
@Value("${queueName}")
private String queueName;
@Value("${topicName}")
private String topicName;
@Value("${spring.activemq.user}")
private String usrName;
@Value("${spring.activemq.password}")
private String password;
@Value("${spring.activemq.broker-url}")
private String brokerUrl;
@Bean
public Queue queue(){
return new ActiveMQQueue(queueName);
}
@Bean
public Topic topic(){
return new ActiveMQTopic(topicName);
}
// 创建连接的工厂
@Bean
public ActiveMQConnectionFactory connectionFactory(){
return new ActiveMQConnectionFactory(usrName, password, brokerUrl);
}
// 队列的监听工厂
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerQueue(ActiveMQConnectionFactory connectionFactory){
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setConnectionFactory(connectionFactory);
return bean;
}
// 主题的监听工厂
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ActiveMQConnectionFactory connectionFactory){
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
// 设置为发布订阅模式,默认情况下使用的生产者消费者方式
bean.setPubSubDomain(true);
bean.setConnectionFactory(connectionFactory);
return bean;
}
}
创建一个controller,注入以下属性:
@Autowired
private JmsMessagingTemplate jms;
@Autowired
private Queue queue;
@Autowired
private Topic topic;
创建一个发送消息的方法:
/**
* 给队列发送消息
* @return
*/
@RequestMapping("/queue")
public String queue(){
for(int i = 0; i < 10; i++){
jms.convertAndSend(queue, "queue" + i);
}
return "queue 发送成功";
}
创建监听该队列的方法,用于接收消息:
// 这里为什么可以去掉 containerFactory = "jmsListenerContainerQueue"
@JmsListener(destination = "publish.queue", containerFactory = "jmsListenerContainerQueue")
// 这个sendTo将消息发送到这个name下,然后监测了这个name的就会收到此消息
@SendTo("out1.queue")
public String recevie(String text){
System.out.println("QueueListener: QueueListener 收到一条信息: " + text);
return "consumer-a received : " + text;
}
既然上面又将此消息@SendTo到了另一个名下,我们可以继续创建一个监听:
@JmsListener(destination = "out1.queue")
public void consumerMsg1(String msg){
System.out.println("consumerMsg1:" + msg);
}
创建一个发送topic的方法:
@RequestMapping("/topic")
public String topic(){
for (int i = 0; i < 10; i++){
jms.convertAndSend(topic,"topic" + i);
}
return "topic 发送成功";
}
创建该topic的监听:
@JmsListener(destination = "publish.topic1", containerFactory = "jmsListenerContainerTopic")
public void recevie(String text){
System.out.println("TopicListener: TopicListener 收到一条信息: " + text);
}
这样一个完整的queue和topic消息中间件就已经搭建完成。
注:
1、queue是点对点,即如果有100条消息在队列中,而又有10个消费者(监听者),那么每个消费者只能消费10条消息。queue如果有消息在队列中,但是没有消费者(监听),消息不会丢失,会一直存在queue中,直到有消费者来消费。
2、topic是一对多,即如果有10条消息在队列中,又有10个消费者,那么每个消费者都能消费这10条消息。如果有消息在topic中,但是没有消费者,消息会丢失,就是说,后面来了消费者,也消费不了之前这些消息。