配置文件管理Exchange、Queue 以及 RoutingKey并自动绑定

yml 中配置 Exchange、Queue 以及 RoutingKey 并自动绑定

  • 1、pom 文件引入 jar 包
  • 2、yml 配置文件
  • 3、实体类
  • 4、自动配置类
  • 5、spring.factories 文件
  • 6、测试

1、pom 文件引入 jar 包

 


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

		<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.12</version>
			<scope>provided</scope>
		</dependency>
		

 

2、yml 配置文件

 

server:
    pror:8080
spring:
    application:
        name: icao
    rabbitmq:
        host: 127.0.0.1
        port: 5672
        username: guest
        password: guest
        #虚拟host 可以不设置,使用server默认host
        # virtual-host: JCcccHost
icao:
   rabbit:
       exchanges:
           - name: icao.sale_order
             type: topic
             queues:
                 - name: icao.sale_order.tt
                   routingKey: 'jf.*'
                 - name: JR-ORDER
                   routingKey: JR-ORDER-ROUTING


 

3、实体类

 

package com.icao.amqp.rabbit;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ExchangeProperties {
    private String exchange;
    private String name;
    private String type;
    private Map<String, Object> properties;
    private List<QueueProperties> queues;
}

 

package com.icao.amqp.rabbit;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Map;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class QueueProperties {
    private String name;
    private String routingKey;
    private Map<String, Object> properties;
}

 

package com.icao.amqp.rabbit;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.boot.context.properties.ConfigurationProperties;

import java.util.List;

/**
 * @author
 * @ClassName: EnjoyitRabbitMqProperties
 * @date: 
 * @Description: rabbitmq的配置文件
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@ConfigurationProperties(prefix = "icao.rabbit")
public class IcaoRabbitProperties {

    // 这里可以在yml文件中自定义order节点,与exchanges同级,子结构RabbitProperties
    private RabbitProperties order;
    private RabbitProperties cashier;
    private RabbitProperties flow;
    private ExchangeProperties saleOrder;
    private List<ExchangeProperties> exchanges;


    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class Async {
        private Integer corePoolSize;
        private Integer maxPoolSize;
        private Integer queueCapacity;
    }

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class RabbitProperties {
        private String exchange;
        private String queue;
        private String routingKey;
    }


    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @Builder
    public static class RmisMqProperties {
        /* 定义exchange*/
        private String exchange;
        /* 定义queue*/
        private String queue;
        /* 定义routingKey*/
        private String routingKey;
        /* 定义有效时间*/
        private long expireTime;
    }
}

 

4、自动配置类

 

package com.icao.amqp.rabbit.autoconfigure;


import com.icao.amqp.rabbit.ExchangeProperties;
import com.icao.amqp.rabbit.IcaoRabbitProperties;
import com.icao.amqp.rabbit.QueueProperties;
import lombok.Setter;
import org.springframework.amqp.core.*;
import org.springframework.beans.factory.config.SingletonBeanRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.context.properties.bind.BindResult;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.beans.Introspector;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;


@Configuration
// @AutoConfigureAfter表示加载RabbitAutoConfiguration.class配置类之后再加载当前类
@AutoConfigureAfter(RabbitAutoConfiguration.class)
@ConditionalOnBean(RabbitAutoConfiguration.class)
@EnableConfigurationProperties(IcaoRabbitProperties.class)
public class ImportRabbitBeanDefinitionRegistrar implements
        ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware {
    @Setter
    private ResourceLoader resourceLoader;

    @Setter
    private Environment environment;

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                        BeanDefinitionRegistry registry) {
        Binder binder = Binder.get(environment);
        BindResult<IcaoRabbitProperties> bindResult =
                binder.bind("icao.rabbit", IcaoRabbitProperties.class);
        IcaoRabbitProperties icaoRabbitProperties = bindResult.orElse(null);
        if (icaoRabbitProperties == null) return;
        List<ExchangeProperties> exchanges = icaoRabbitProperties.getExchanges();
        if (CollectionUtils.isEmpty(exchanges)) return;
        for (ExchangeProperties exchangeProperties : exchanges) {
            Exchange exchange = buildExchange(exchangeProperties);
            if (exchange == null) continue;
            registerBeanDefinitions(exchange, registry);
            List<QueueProperties> queueProperties = exchangeProperties.getQueues();
            if (CollectionUtils.isEmpty(queueProperties)) continue;
            for (QueueProperties properties : queueProperties) {
                Queue queue = buildQueue(properties);
                registerBeanDefinitions(queue, registry);
                Binding binding = buildBinding(exchange, properties, queue);
                registerBeanDefinitions(binding, registry);
            }
        }
    }

    private Binding buildBinding(Exchange exchange, QueueProperties properties, Queue queue) {
        return BindingBuilder.
                bind(queue).
                to(exchange).
                with(properties.getRoutingKey()).noargs();
    }

    private Queue buildQueue(QueueProperties queueProperties) {
        return new Queue(queueProperties.getName(), true, false, false,
                queueProperties.getProperties());
    }

    private Exchange buildExchange(ExchangeProperties exchangeProperties) {
        String name = Optional.ofNullable(exchangeProperties.getName()).orElseGet(exchangeProperties::getExchange);
        if (StringUtils.isEmpty(name)) return null;
        String type = Optional.ofNullable(exchangeProperties.getType()).orElse(ExchangeTypes.TOPIC);
        Map<String, Object> arguments = Optional.ofNullable(exchangeProperties.getProperties()).orElseGet(HashMap::new);
        return new ExchangeBuilder(name, type).withArguments(arguments).build();
    }

    private <T> void registerBeanDefinitions(Exchange exchange, BeanDefinitionRegistry registry) {
        if (registry instanceof SingletonBeanRegistry) {
            SingletonBeanRegistry beanRegistry = (SingletonBeanRegistry) registry;
            beanRegistry.registerSingleton(
                    exchange.getName().
                            concat(".").
                            concat(getBeanName(exchange.getClass())), exchange);
        }
    }

    private <T> String getBeanName(Class<T> tClass) {
        String shortClassName = ClassUtils.getShortName(tClass);
        return Introspector.decapitalize(shortClassName);
    }

    private void registerBeanDefinitions(Queue queue, BeanDefinitionRegistry registry) {
        if (registry instanceof SingletonBeanRegistry) {
            SingletonBeanRegistry beanRegistry = (SingletonBeanRegistry) registry;
            beanRegistry.registerSingleton(queue.getName().
                    concat(".").
                    concat(getBeanName(queue.getClass())), queue);
        }
    }

    private void registerBeanDefinitions(Binding binding, BeanDefinitionRegistry registry) {
        if (registry instanceof SingletonBeanRegistry) {
            SingletonBeanRegistry beanRegistry = (SingletonBeanRegistry) registry;
            beanRegistry.registerSingleton(binding.getExchange().
                    concat(".").
                    concat(binding.getDestination()).
                    concat(".").
                    concat(getBeanName(binding.getClass())), binding);
        }
    }
}

 

5、spring.factories 文件

 
spring.factories 文件是用于启动时自动加载 ImportRabbitBeanDefinitionRegistrar 配置文件,注意 spring.factories 文件所在的目录结构。
 


org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.icao.amqp.rabbit.autoconfigure.ImportRabbitBeanDefinitionRegistrar

 
文件目录:
配置文件管理Exchange、Queue 以及 RoutingKey并自动绑定_第1张图片

6、测试

 
运行项目前,查看Rabbit MQ 管控台:

配置文件管理Exchange、Queue 以及 RoutingKey并自动绑定_第2张图片

配置文件管理Exchange、Queue 以及 RoutingKey并自动绑定_第3张图片

运行项目后,再次查看Rabbit MQ 管控台:

配置文件管理Exchange、Queue 以及 RoutingKey并自动绑定_第4张图片

配置文件管理Exchange、Queue 以及 RoutingKey并自动绑定_第5张图片

配置文件管理Exchange、Queue 以及 RoutingKey并自动绑定_第6张图片

配置文件管理Exchange、Queue 以及 RoutingKey并自动绑定_第7张图片

配置文件管理Exchange、Queue 以及 RoutingKey并自动绑定_第8张图片
 
 
 
 
 
 
 
 
.

你可能感兴趣的:(Rabbit,Mq)