SpringBoot整合ActiveMQ(整理四 发布订阅模式(pub/sub),及同时支持点对点和发布订阅模型)

1、配置文件

#整合jms测试,安装在别的机器,防火墙和端口号记得开放
spring.activemq.broker-url=tcp://127.0.0.1:61616
#集群配置
#spring.activemq.broker-url=failover:(tcp://localhost:61616,tcp://localhost:61617)
spring.activemq.user=admin
spring.activemq.password=admin
#下列配置要增加依赖。是否开启activemq连接池
spring.activemq.pool.enabled=true
#最大连接数
spring.activemq.pool.max-connections=100

#开启支持发布订阅模型,activemq默认只支持点对点
spring.jms.pub-sub-domain=true

2、启动类

import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.jms.annotation.EnableJms;
import javax.jms.Queue;
import javax.jms.Topic;

@SpringBootApplication
@EnableJms //开启支持jms
public class FbiaoApplication {

	@Bean   //将主题对象交给spring管理
	public Topic topic(){
		return new ActiveMQTopic("video.topic");
	}

	@Bean   //交给spring管理,方便后续注入
	public Queue queue(){
	    //common.queue默认的消息队列
		return new ActiveMQQueue("common.queue");
	}

	public static void main(String[] args) {
		SpringApplication.run(FbiaoApplication.class, args);
	}
}

3、发布生产者

import javax.jms.Destination;
/**
 * 功能描述:消息生产
 */
public interface ProducerService {
	/**
	 * 功能描述:指定消息队列,还有消息
	 * @param destination
	 * @param message
	 */
	public void sendMessage(Destination destination, final String message);
	
	/**
	 * 功能描述:使用默认消息队列, 发送消息
	 * @param message
	 */
	public void sendMessage( final String message);
	/**
	 * 功能描述:消息发布者
	 * @param msg
	 */
	public void publish(String msg);
}


import org.springframework.jms.core.JmsMessagingTemplate;
import javax.jms.Destination;
import javax.jms.Queue;
import javax.jms.Topic;

/**
 * 功能描述:消息生产者
 */
@Service
public class ProducerServiceImpl implements ProducerService {
	@Autowired
	private Queue queue;

	@Autowired
	private JmsMessagingTemplate jmsTemplate; //用来发送消息到broker的对象
	
	//发送消息,destination是发送到的队列,message是待发送的消息
	@Override
	public void sendMessage(Destination destination, String message) {
		jmsTemplate.convertAndSend(destination, message);
	}

	//发送消息,destination是发送到的队列,message是待发送的消息
	@Override
	public void sendMessage(final String message) {
		jmsTemplate.convertAndSend(this.queue,message);
	}

	//=======发布订阅相关代码=========
	@Autowired
	private Topic topic;
	 @Override
	public void publish(String msg) {
		this.jmsTemplate.convertAndSend(this.topic, msg);
	}
}

4、测试发布订阅者

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class TopicSub {

	@JmsListener(destination="video.topic")
	public void receive1(String text){
		System.out.println("video.topic 消费者:receive1="+text);
	}
	@JmsListener(destination="video.topic")
	public void receive2(String text){
		System.out.println("video.topic 消费者:receive2="+text);
	}
	@JmsListener(destination="video.topic")
	public void receive3(String text){
		System.out.println("video.topic 消费者:receive3="+text);
	}
}

5、测试发布生产者消息接口

import javax.jms.Destination;
import org.apache.activemq.command.ActiveMQQueue;
/**
 * 功能描述:模拟下单
 */
@RestController
@RequestMapping("/api/activemq")
public class OrderController {
	
	@Autowired
	private ProducerService producerService;
	/**
	 * 功能描述:模拟下单
	 * @param msg 下单信息
	 * @return
	 */
	@GetMapping("order")
	public Object order(String msg){
		
		Destination destination = new ActiveMQQueue("order.queue");
		
		producerService.sendMessage(destination, msg);
	
       	return JsonData.buildSuccess();
	}

	@GetMapping("common")
	public Object common(String msg){
		producerService.sendMessage(msg);
       	return JsonData.buildSuccess();
	}
	//消息发布
	@GetMapping("topic")
	public Object topic(String msg){
		producerService.publish(msg);
		return JsonData.buildSuccess();
	}
}

6、测试发布生产者,订阅者

在这里插入图片描述
在这里插入图片描述

192.168.1.188:8080/api/activemq/topic?msg=发布订阅消息1
192.168.1.188:8080/api/activemq/common?msg=测试点对点默认消息队列
192.168.1.188:8080/api/activemq/order?msg=测试点对点指定消息队列
控制台并未打印出点对点的生产消费信息,但队列里有尚未消费的消息,消费者数量113
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

7、我们知道activemq默认只支持点对点模型,如何让它同时支持点对点和发布订阅模型呢?

7.1、解决办法

(1)默认消费者并不会消费订阅发布类型的消息,这是由于springboot默认采用的是p2p模式进行消息的监听
修改配置:spring.jms.pub-sub-domain=true使其支持发布订阅模型
(2)@JmsListener如果不指定独立的containerFactory的话是只能消费queue消息
修改订阅者container:containerFactory=“jmsListenerContainerTopic”
(3)需要给topic定义独立的JmsListenerContainer
@Bean
public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) {
DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
bean.setPubSubDomain(true);
bean.setConnectionFactory(activeMQConnectionFactory);
return bean;
}
(4)在配置文件里面,注释掉 #spring.jms.pub-sub-domain=true

7.2、修改启动类

import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;

import javax.jms.ConnectionFactory;
import javax.jms.Queue;
import javax.jms.Topic;

@SpringBootApplication
@EnableJms //开启支持jms
public class FbiaoApplication {

	@Bean   //将主题对象交给spring管理
	public Topic topic(){
		return new ActiveMQTopic("video.topic");
	}

	@Bean   //交给spring管理,方便后续注入
	public Queue queue(){
	    //common.queue默认的消息队列
		return new ActiveMQQueue("common.queue");
	}

	public static void main(String[] args) {
		SpringApplication.run(FbiaoApplication.class, args);
	}

	@Bean
    public JmsListenerContainerFactory<?> jmsListenerContainerTopic(ConnectionFactory activeMQConnectionFactory) {
        DefaultJmsListenerContainerFactory bean = new DefaultJmsListenerContainerFactory();
        bean.setPubSubDomain(true);
        bean.setConnectionFactory(activeMQConnectionFactory);
        return bean;
    }
}

7.3、修改订阅者

import org.springframework.jms.annotation.JmsListener;
@Component
public class TopicSub {
	@JmsListener(destination="video.topic", containerFactory="jmsListenerContainerTopic")
	public void receive1(String text){
		System.out.println("video.topic 消费者:receive1="+text);
	}
	@JmsListener(destination="video.topic", containerFactory="jmsListenerContainerTopic")
	public void receive2(String text){
		System.out.println("video.topic 消费者:receive2="+text);
	}
	@JmsListener(destination="video.topic", containerFactory="jmsListenerContainerTopic")
	public void receive3(String text){
		System.out.println("video.topic 消费者:receive3="+text);
	}
}

7.4在配置文件里面,注释掉

#spring.jms.pub-sub-domain=true

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

192.168.1.188:8080/api/activemq/topic?msg=发布订阅消息2
192.168.1.188:8080/api/activemq/common?msg=测试点对点默认消息队列1
192.168.1.188:8080/api/activemq/order?msg=测试点对点指定消息队列1
在这里插入图片描述

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Spring Boot中整合ActiveMQ进行订阅,你需要按照以下步骤进行配置和实现: 1. 依赖:在`pom.xml`文件中添加以下依赖项: ``` <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> ``` 2. 配置参数:在`application.yml`或`application.properties`文件中配置ActiveMQ连接信息和订阅相关参数,例如: ``` spring: activemq: broker-url: tcp://localhost:61616 # ActiveMQ连接地址 user: admin # ActiveMQ用户名 password: admin # ActiveMQ密码 jms: pub-sub-domain: true # 设置为true表示使用发布订阅模式,默认为false(点对点模式) ``` 3. 创建订阅者:在你的代码中创建一个订阅者类,用于接收消息。可以使用`@JmsListener`注解来标识一个方法作为消息监听器,例如: ```java @Service public class MySubscriber { @JmsListener(destination = "your-topic-name") public void receiveMessage(String message) { // 处理接收到的消息 System.out.println("Received message: " + message); } } ``` 在上面的例子中,`your-topic-name`是你要订阅的主题名称。 4. 发布消息:在需要发布消息的地方,注入`JmsTemplate`对象,然后使用`convertAndSend`方法发送消息,例如: ```java @Service public class MyPublisher { @Autowired private JmsTemplate jmsTemplate; public void sendMessage(String message) { jmsTemplate.convertAndSend("your-topic-name", message); } } ``` 在上面的例子中,`your-topic-name`是你要发布消息的主题名称。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值