<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>
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
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;
}
}
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);
}
}
}
spring.factories 文件是用于启动时自动加载 ImportRabbitBeanDefinitionRegistrar 配置文件,注意 spring.factories 文件所在的目录结构。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.icao.amqp.rabbit.autoconfigure.ImportRabbitBeanDefinitionRegistrar
运行项目前,查看Rabbit MQ 管控台:
运行项目后,再次查看Rabbit MQ 管控台: