JMS之ActiveMQ(三):springboot集成ActiveMQ

第一章讲了ActiveMQ的安装,本章讲解springboot集成ActiveMQ。

首先在pom中导入对ActiveMQ的依赖

		<!--ActiveMQ支持-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-activemq</artifactId>
		</dependency>

然后在application.yml中配置ActiveMQ(默认只支持发送和接收queue消息)

spring:
  activemq:
    broker-url: tcp://localhost:61616
    user: admin
    password: admin

创建消息生产者,类上要加@Service或者@Component,交给spring管理

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Service;

import javax.jms.Destination;

@Service("producer")
public class Producer {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    public void sendMessage(Destination destination, String message) {
        jmsMessagingTemplate.convertAndSend(destination,message);
    }
}

创建消息消费者

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class Consumer {
    private final static Logger logger = LoggerFactory.getLogger(Consumer.class);
    @JmsListener(destination = "springboot.queue.test")
    public void receiveQueue(String text){
        logger.info("Consumer接受的消息:"+text);
    }
}

测试类

import com.springboot.first.task.Producer;
import org.apache.activemq.command.ActiveMQQueue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.jms.Destination;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ActiveMqTest {
    @Autowired
    private Producer producer;

    @Test
    public void test() throws InterruptedException {
        Destination destination = new ActiveMQQueue("springboot.queue.test");
        for (int i = 0; i < 10; i++) {
            producer.sendMessage(destination, "你好,我是:" + i);
        }
    }
}

测试结果:


若要支持ActiveMQ连接池,则在pom中还要添加依赖:

		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-pool</artifactId>
		</dependency>

application.yml

spring:
  activemq:
    broker-url: tcp://localhost:61616
    user: admin
    password: admin
    #指定是否为内存模式,默认true
    in-memory: true
    pool:
      #是否使用PooledConnectionFactory,默认false(默认使用ConnectionFactory),若要设为true,则需添加activemq-pool依赖
      enabled: true
      #最大连接数
      max-connections: 50
      #连接超时时间
      expiry-timeout: 10000
      #空闲时间
      idle-timeout: 30000

实现双向队列

创建一个新的消息消费者Consumer2.java

扫描二维码关注公众号,回复: 1840721 查看本文章
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;

@Component
public class Consumer2 {
    private final static Logger logger = LoggerFactory.getLogger(Consumer2.class);
    @JmsListener(destination = "springboot.queue")
    @SendTo("out.queue")//将return返回的值再添加到out.queue队列中
    public String receiveQueue(String text){
        logger.info("Consumer2接受的消息:"+text);
        return "返回的信息"+text;
    }
}

在Producer.java中添加一个方法,使其既能产生报文,又能消费队列中的报文。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.jms.core.JmsMessagingTemplate;
import org.springframework.stereotype.Component;

import javax.jms.Destination;

@Component("producer")
public class Producer {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    public void sendMessage(Destination destination, String message) {
        jmsMessagingTemplate.convertAndSend(destination, message);
    }
    //监听out.queue
    @JmsListener(destination = "out.queue")
    public void consumerMessage(String text) {
        System.out.println("从out.queue收到的回复报文为:" + text);
    }
}

再运行测试代码,结果如下:


支持同时发送和接收queue和topic消息

默认是只发送和接收queue消息,如要支持topic,则application.yml中要添加如下配置,但是添加了以下配置就无法发送和接收queue消息了,也就是两者只能选择一种。

spring:
  jms:
    #发送和接受topic消息,默认false
    pub-sub-domain: false

怎么能够让两者共存呢?

新建一个JMS的配置类

import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
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.ConnectionFactory;
import javax.jms.Queue;
import javax.jms.Topic;

@Configuration
public class JMSConfig {
    public final static String QUEUE = "springboot.queue";
    public final static String TOPIC = "springboot.topic";

    @Bean
    public Queue queue() {
        return new ActiveMQQueue(QUEUE);
    }

    @Bean
    public Topic topic() {
        return new ActiveMQTopic(TOPIC);
    }

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

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

}

生产者代码不变,消费者代码如下:

import com.springboot.first.config.JMSConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Component;

@Component
public class Consumer2 {
    private final static Logger logger = LoggerFactory.getLogger(Consumer2.class);

    //    @JmsListener(destination = "springboot.queue")
//    @SendTo("out.queue")
//    public String receiveQueue(String text){
//        logger.info("Consumer2接受的消息:"+text);
//        return "返回的信息"+text;
//    }
    @JmsListener(destination = JMSConfig.QUEUE, containerFactory = "jmsListenerContainerQueue")
    public void receiveQueue(String text) {
        logger.info("接收到的queue消息:" + text);
    }

    @JmsListener(destination = JMSConfig.TOPIC, containerFactory = "jmsListenerContainerTopic")
    public void receiveTopic(String text) {
        logger.info("接收到的topic消息:" + text);
    }
}

测试类:

import com.springboot.first.task.Producer;
import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.jms.Destination;
import javax.jms.Queue;
import javax.jms.Topic;

@RunWith(SpringRunner.class)
@SpringBootTest
public class ActiveMqTest {
    @Autowired
    private Producer producer;
    @Autowired
    private Queue queue;
    @Autowired
    private Topic topic;

    @Test
    public void test() {
        for (int i = 0; i < 10; i++) {
            producer.sendMessage(queue, "你好,我是:" + i);
            producer.sendMessage(topic, "你好,我是:" + i);
        }
    }
}

测试结果如下图所示:


queue消息和topic消息可以同时发送接收了。

猜你喜欢

转载自blog.csdn.net/qq_23543983/article/details/80506016