消息队列篇-简单使用


一、引入springboot-amqp启动器

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

二、查看配置类RabbitAutoConfiguration

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.boot.autoconfigure.amqp;

import com.rabbitmq.client.Channel;
import java.time.Duration;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionNameStrategy;
import org.springframework.amqp.rabbit.connection.RabbitConnectionFactoryBean;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitMessagingTemplate;
import org.springframework.amqp.rabbit.core.RabbitOperations;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Ssl;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Template;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties.Cache.Connection;
import org.springframework.boot.autoconfigure.amqp.RabbitRetryTemplateCustomizer.Target;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({RabbitTemplate.class, Channel.class})
@EnableConfigurationProperties({RabbitProperties.class})
@Import({RabbitAnnotationDrivenConfiguration.class})
public class RabbitAutoConfiguration {
    public RabbitAutoConfiguration() {
    }

    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnClass({RabbitMessagingTemplate.class})
    @ConditionalOnMissingBean({RabbitMessagingTemplate.class})
    @Import({RabbitAutoConfiguration.RabbitTemplateConfiguration.class})
    protected static class MessagingTemplateConfiguration {
        protected MessagingTemplateConfiguration() {
        }

        @Bean
        @ConditionalOnSingleCandidate(RabbitTemplate.class)
        public RabbitMessagingTemplate rabbitMessagingTemplate(RabbitTemplate rabbitTemplate) {
            return new RabbitMessagingTemplate(rabbitTemplate);
        }
    }

    @Configuration(
        proxyBeanMethods = false
    )
    @Import({RabbitAutoConfiguration.RabbitConnectionFactoryCreator.class})
    protected static class RabbitTemplateConfiguration {
        protected RabbitTemplateConfiguration() {
        }

        @Bean
        @ConditionalOnSingleCandidate(ConnectionFactory.class)
        @ConditionalOnMissingBean({RabbitOperations.class})
        public RabbitTemplate rabbitTemplate(RabbitProperties properties, ObjectProvider<MessageConverter> messageConverter, ObjectProvider<RabbitRetryTemplateCustomizer> retryTemplateCustomizers, ConnectionFactory connectionFactory) {
            PropertyMapper map = PropertyMapper.get();
            RabbitTemplate template = new RabbitTemplate(connectionFactory);
            messageConverter.ifUnique(template::setMessageConverter);
            template.setMandatory(this.determineMandatoryFlag(properties));
            Template templateProperties = properties.getTemplate();
            if (templateProperties.getRetry().isEnabled()) {
                template.setRetryTemplate((new RetryTemplateFactory((List)retryTemplateCustomizers.orderedStream().collect(Collectors.toList()))).createRetryTemplate(templateProperties.getRetry(), Target.SENDER));
            }

            templateProperties.getClass();
            map.from(templateProperties::getReceiveTimeout).whenNonNull().as(Duration::toMillis).to(template::setReceiveTimeout);
            templateProperties.getClass();
            map.from(templateProperties::getReplyTimeout).whenNonNull().as(Duration::toMillis).to(template::setReplyTimeout);
            templateProperties.getClass();
            map.from(templateProperties::getExchange).to(template::setExchange);
            templateProperties.getClass();
            map.from(templateProperties::getRoutingKey).to(template::setRoutingKey);
            templateProperties.getClass();
            map.from(templateProperties::getDefaultReceiveQueue).whenNonNull().to(template::setDefaultReceiveQueue);
            return template;
        }

        private boolean determineMandatoryFlag(RabbitProperties properties) {
            Boolean mandatory = properties.getTemplate().getMandatory();
            return mandatory != null ? mandatory : properties.isPublisherReturns();
        }

        @Bean
        @ConditionalOnSingleCandidate(ConnectionFactory.class)
        @ConditionalOnProperty(
            prefix = "spring.rabbitmq",
            name = {"dynamic"},
            matchIfMissing = true
        )
        @ConditionalOnMissingBean
        public AmqpAdmin amqpAdmin(ConnectionFactory connectionFactory) {
            return new RabbitAdmin(connectionFactory);
        }
    }

    @Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnMissingBean({ConnectionFactory.class})
    protected static class RabbitConnectionFactoryCreator {
        protected RabbitConnectionFactoryCreator() {
        }

        @Bean
        public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties properties, ObjectProvider<ConnectionNameStrategy> connectionNameStrategy) throws Exception {
            PropertyMapper map = PropertyMapper.get();
            CachingConnectionFactory factory = new CachingConnectionFactory((com.rabbitmq.client.ConnectionFactory)this.getRabbitConnectionFactoryBean(properties).getObject());
            properties.getClass();
            map.from(properties::determineAddresses).to(factory::setAddresses);
            properties.getClass();
            map.from(properties::isPublisherReturns).to(factory::setPublisherReturns);
            properties.getClass();
            map.from(properties::getPublisherConfirmType).whenNonNull().to(factory::setPublisherConfirmType);
            org.springframework.boot.autoconfigure.amqp.RabbitProperties.Cache.Channel channel = properties.getCache().getChannel();
            channel.getClass();
            map.from(channel::getSize).whenNonNull().to(factory::setChannelCacheSize);
            channel.getClass();
            map.from(channel::getCheckoutTimeout).whenNonNull().as(Duration::toMillis).to(factory::setChannelCheckoutTimeout);
            Connection connection = properties.getCache().getConnection();
            connection.getClass();
            map.from(connection::getMode).whenNonNull().to(factory::setCacheMode);
            connection.getClass();
            map.from(connection::getSize).whenNonNull().to(factory::setConnectionCacheSize);
            connectionNameStrategy.getClass();
            map.from(connectionNameStrategy::getIfUnique).whenNonNull().to(factory::setConnectionNameStrategy);
            return factory;
        }

        private RabbitConnectionFactoryBean getRabbitConnectionFactoryBean(RabbitProperties properties) throws Exception {
            PropertyMapper map = PropertyMapper.get();
            RabbitConnectionFactoryBean factory = new RabbitConnectionFactoryBean();
            properties.getClass();
            map.from(properties::determineHost).whenNonNull().to(factory::setHost);
            properties.getClass();
            map.from(properties::determinePort).to(factory::setPort);
            properties.getClass();
            map.from(properties::determineUsername).whenNonNull().to(factory::setUsername);
            properties.getClass();
            map.from(properties::determinePassword).whenNonNull().to(factory::setPassword);
            properties.getClass();
            map.from(properties::determineVirtualHost).whenNonNull().to(factory::setVirtualHost);
            properties.getClass();
            map.from(properties::getRequestedHeartbeat).whenNonNull().asInt(Duration::getSeconds).to(factory::setRequestedHeartbeat);
            Ssl ssl = properties.getSsl();
            if (ssl.determineEnabled()) {
                factory.setUseSSL(true);
                ssl.getClass();
                map.from(ssl::getAlgorithm).whenNonNull().to(factory::setSslAlgorithm);
                ssl.getClass();
                map.from(ssl::getKeyStoreType).to(factory::setKeyStoreType);
                ssl.getClass();
                map.from(ssl::getKeyStore).to(factory::setKeyStore);
                ssl.getClass();
                map.from(ssl::getKeyStorePassword).to(factory::setKeyStorePassphrase);
                ssl.getClass();
                map.from(ssl::getTrustStoreType).to(factory::setTrustStoreType);
                ssl.getClass();
                map.from(ssl::getTrustStore).to(factory::setTrustStore);
                ssl.getClass();
                map.from(ssl::getTrustStorePassword).to(factory::setTrustStorePassphrase);
                ssl.getClass();
                map.from(ssl::isValidateServerCertificate).to((validate) -> {
                    factory.setSkipServerCertificateValidation(!validate);
                });
                ssl.getClass();
                map.from(ssl::getVerifyHostname).to(factory::setEnableHostnameVerification);
            }

            properties.getClass();
            map.from(properties::getConnectionTimeout).whenNonNull().asInt(Duration::toMillis).to(factory::setConnectionTimeout);
            factory.afterPropertiesSet();
            return factory;
        }
    }
}

往容器中自动配置了RabbitMessagingTemplate、RabbitTemplate、AmqpAdmin、CachingConnectionFactory四个组件。

三、AmqpAdmin

在这里插入图片描述
AmqpAdmin配置spring和RabbitMQ连接信息,从配置文件中读取,以spring.rabbitmq开头

1.配置gulimall-order模块的yml文件

添加RabbitMQ连接信息
在这里插入图片描述

2.在启动类添加@EnableRabbit注解

开启RabbitMQ服务
在这里插入图片描述

3.使用AmqpAdmin创建Exchange交换器

@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
class GulimallOrderApplicationTests {

	@Autowired
	AmqpAdmin amqpAdmin;

	//创建交换器
	@Test
	public void  createExchange(){
		//创建Direct类型交换器
		DirectExchange directExchange = new DirectExchange("java-direct-exchange", true, false);
		amqpAdmin.declareExchange(directExchange);
		log.info("交换器创建成功");
	}
}

在这里插入图片描述
创建成功:
在这里插入图片描述

4.使用AmqpAdmin创建Queue队列

public void  createQueue(){
	//创建Queue
	Queue queue = new Queue("java-queue", true, false,false);
	amqpAdmin.declareQueue(queue);
	log.info("队列创建成功");
}

在这里插入图片描述
创建成功:
在这里插入图片描述

5.使用AmqpAdmin创建Binding绑定

//创建绑定
@Test
public void  createBinding(){
	//创建Queue
	//String destination,   需要绑定的Queue/Exchange名称
	// Binding.DestinationType destinationType,  需要绑定类型:Queue/Exchange
	// String exchange, 	需要绑定的Exchange名称
	// String routingKey,   路由键
	// @Nullable Map<String, Object> arguments  参数
	Binding binding = new Binding("java-queue",
			Binding.DestinationType.QUEUE,
			"java-direct-exchange",
			"hello-java",
			null);
	amqpAdmin.declareBinding(binding);
	log.info("绑定成功");
}

在这里插入图片描述
绑定成功:
在这里插入图片描述

四、RabbitTemplate

1.发送字符串纯文本消息

@Autowired
RabbitTemplate rabbitTemplate;

@Test
public void sendMessageTest(){

	/**
	 * 发送消息
	 */
	rabbitTemplate.convertAndSend("java-direct-exchange","hello-java","第一条消息");
}

在这里插入图片描述
消息发送成功:
在这里插入图片描述
在这里插入图片描述

2.发送对象消息

@Autowired
RabbitTemplate rabbitTemplate;

@Test
public void sendMessageTest(){

	/**
	 * 发送消息
	 */
	OrderReturnApplyEntity orderReturnApplyEntity = new OrderReturnApplyEntity();
	orderReturnApplyEntity.setId(1L);
	orderReturnApplyEntity.setCreateTime(new Date());
	orderReturnApplyEntity.setSkuName("iPhone");
	
	rabbitTemplate.convertAndSend("java-direct-exchange","hello-java",orderReturnApplyEntity);
	log.info("发送成功");
}

在这里插入图片描述
对象必须实现Serializable接口。

1.默认序列化机制是jdk字节流

获取消息:
在这里插入图片描述

在这里插入图片描述

2.修改RabbitMQ序列化机制为JSON序列化

新建RabbitConfig配置类,在容器中重启注入自定义的messageConverter

package com.simon.gulimall.order.config;

import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyRabbitConfig {
    @Bean
    public MessageConverter messageConverter(){
        return  new Jackson2JsonMessageConverter();
    }
}

MessageConverter 接口的实现,其中就有JacksonMessageConverter
在这里插入图片描述

3.再次发送对象消息

结果:变为JSON格式了。
在这里插入图片描述

五、监听消息RabbitListener、RabbitHandler

使用 @RabbitListener @RabbitHandler必须在启动类上加@EnableRabbit

1.@RabbitListener

在这里插入图片描述

//监听消息  进行消费
 @RabbitListener(queues = "java-queue")
 public void  recivedMessage(Message msg){
     byte[] body = msg.getBody();
     MessageProperties messageProperties = msg.getMessageProperties();
     System.out.println("body:"+new String(body));
     System.out.println("messageProperties:"+messageProperties);

 }

在这里插入图片描述
此时获取的body就是对象转成的json。可以直接使用对象进行接收,spring自动转换:
在这里插入图片描述

2.@RabbitHandler

如果监听同一个队列的两种或多种消息,进行不同逻辑的处理,这时就需要@RabbitListener和@RabbitHandler组合使用。

在这里插入图片描述
@RabbitListener(queues = “java-queue”)放在类上进行标注
@RabbitHandler放在方法上标注,表明监听

@Service("orderItemService")
@RabbitListener(queues = "java-queue")
public class OrderItemServiceImpl extends ServiceImpl<OrderItemDao, OrderItemEntity> implements OrderItemService {
    //监听消息  进行消费

    /**
     * 监听java-queue队列中OrderReturnApplyEntity的消息
     * @param msg
     * @param orderReturnApplyEntity
     */
    @RabbitHandler
    public void  recivedMessage(Message msg, OrderReturnApplyEntity orderReturnApplyEntity){
        System.out.println("orderReturnApplyEntity:"+orderReturnApplyEntity);

    }

    /**
     * 监听java-queue队列中OrderEntity的消息
     * @param msg
     * @param OrderEntity
     */
    @RabbitHandler
    public void  recivedMessage2(Message msg, OrderEntity orderEntity){
        System.out.println("orderEntity:"+orderEntity);

    }
 }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值