springboot实现rabbitmq动态创建交换机,队列以及交换机、队列绑定
1. 数据库准备
drop table if exists mq_config;
create table mq_config
(
mq_id varchar(200) not null comment '交换机id',
exchange_type char(1) comment '交换机类型(0:DIRECT直连交换机; 1:TOPIC主题交换机; 2:FANOUT扇形交换机; 3:HEADERS头交换机)',
exchange_name varchar(200) comment '交换机名称',
queue_name varchar(200) comment '队列名称',
binding varchar(200) comment '绑定关系',
delay_type char(1) comment '是否死信队列(0:是;1:否)',
version bigint(20) default 0 comment '乐观锁',
del_flag char(1) default '0' comment '删除标志(0:存在; 1:删除)',
status char(1) default '0' comment '记录状态(0:在用; 1:停用)',
create_by varchar(64) comment '创建人',
create_time timestamp(0) default CURRENT_TIMESTAMP comment '创建时间',
update_by varchar(64) comment '修改人',
update_time datetime(0) default CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP comment '修改时间',
remark varchar(500) comment '备注',
primary key (mq_id)
);
alter table mq_config comment 'mq配置表';
2. 依赖引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-micro-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.github.xiaoymin</groupId>
<artifactId>knife4j-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
3. yml配置
server:
port: 8080
spring:
datasource:
druid:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/schedule?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
username: root
password: root
filters: stat,wall
max-active: 100
initial-size: 1
max-wait: 60000
min-idle: 1
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: select 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: true
max-open-prepared-statements: 50
max-pool-prepared-statement-per-connection-size: 20
web-stat-filter:
enabled: true
exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
url-pattern: /*
stat-view-servlet:
enabled: true
url-pattern: /druid/*
allow:
deny:
login-username: admin
login-password: admin
reset-enable: true
rabbitmq:
host: 10.168.1.200
port: 5672
virtual-host: test
username: admin
password: admin
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
4. 创建mq操作类
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MqVo implements Serializable {
private static final long serialVersionUID = -3630888028848412302L;
@ApiModelProperty(value = "交换机类型(0:DIRECT直连交换机; 1:TOPIC主题交换机; 2:FANOUT扇形交换机; 3:HEADERS头交换机)")
private String exchangeType;
@ApiModelProperty(value = "交换机名称")
private String exchangeName;
@ApiModelProperty(value = "队列名称")
private String queueName;
@ApiModelProperty(value = "绑定关系")
private String binding;
@ApiModelProperty(value = "是否死信队列(0:是;1:否)")
private String delayType;
@ApiModelProperty(value = "操作类型(0:新增; 1:删除)")
private int type;
}
5. mq操作方法
@Slf4j
@Component
public class MqUtils {
@Resource
private ConnectionFactory connectionFactory;
public void mqOperate(MqVo mqVo) {
String exchangeType = mqVo.getExchangeType();
log.info("exchangeType -> {}", exchangeType);
String queueName = mqVo.getQueueName();
log.info("queueName -> {}", queueName);
String exchangeName = mqVo.getExchangeName();
log.info("exchangeName -> {}", exchangeName);
String binding = mqVo.getBinding();
log.info("binding -> {}", binding);
String delayType = mqVo.getDelayType();
log.info("delayType -> {}", delayType);
int status = mqVo.getType();
RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
if (status == 0) {
rabbitAdmin.declareQueue(new Queue(queueName));
rabbitAdmin.declareExchange(getExchange(exchangeType, exchangeName, delayType));
rabbitAdmin.declareBinding(new Binding(queueName, Binding.DestinationType.QUEUE, exchangeName, binding, null));
} else {
rabbitAdmin.deleteQueue(queueName);
rabbitAdmin.deleteExchange(exchangeName);
rabbitAdmin.removeBinding(new Binding(queueName, Binding.DestinationType.QUEUE, exchangeName, binding, null));
}
close();
}
private Exchange getExchange(String exchangeType, String exchangeName, String delayType) {
Exchange exchange = new DirectExchange(exchangeName);
String zero = "0";
switch (exchangeType) {
case "0":
if (zero.equals(delayType)) {
Map<String, Object> map = new HashMap<>(1);
map.put("x-delayed-type", "direct");
exchange = new CustomExchange(exchangeName, "x-delayed-message", true, false, map);
} else {
exchange = new DirectExchange(exchangeName);
}
break;
case "1":
if (zero.equals(delayType)) {
} else {
exchange = new TopicExchange(exchangeName);
}
break;
case "2":
if (zero.equals(delayType)) {
} else {
exchange = new FanoutExchange(exchangeName);
}
break;
case "3":
if (zero.equals(delayType)) {
} else {
exchange = new HeadersExchange(exchangeName);
}
break;
default:
break;
}
return exchange;
}
public void close(){
try (Connection connection = connectionFactory.createConnection()){
try (Channel channel = connection.createChannel(true)){
com.rabbitmq.client.Connection connection1 = channel.getConnection();
connection1.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
6. service接口
@Slf4j
@Service("mqConfigService")
public class MqConfigServiceImpl extends ServiceImpl<MqConfigDao, MqConfig> implements MqConfigService {
@Resource
private MqUtils mqUtils;
@Override
public boolean add(MqConfig mqConfig) {
boolean save = save(mqConfig);
if (save) {
status(mqConfig);
}
return save;
}
@Override
public boolean update(MqConfig mqConfig) {
MqConfig byId = getById(mqConfig.getMqId());
boolean b = updateById(mqConfig);
if (b) {
addOrDelMq(byId, 1);
status(mqConfig);
}
return b;
}
private void status(MqConfig mqConfig) {
if ("0".equals(mqConfig.getStatus())) {
addOrDelMq(mqConfig, 0);
}
}
public void addOrDelMq(MqConfig mqConfig, int type){
mqUtils.mqOperate(
MqVo
.builder()
.exchangeType(mqConfig.getExchangeType())
.queueName(mqConfig.getExchangeName())
.exchangeName(mqConfig.getExchangeName())
.binding(mqConfig.getBinding())
.delayType(mqConfig.getDelayType())
.type(type)
.build()
);
}
@Override
public boolean delete(String[] mqIds) {
Boolean b = false;
for (String mqId : mqIds) {
MqConfig mqConfig = getById(mqId);
b = removeById(mqId);
if (b) {
addOrDelMq(mqConfig, 1);
}
}
return b;
}
}
7.controller接口
@RestController
@RequestMapping("mqConfig")
public class MqConfigController {
@Resource
private MqConfigService mqConfigService;
@ApiOperation(value = "新增mq配置")
@PostMapping(value = "add", produces = "application/json;charset=utf-8")
public ApiResult<Boolean> add(MqConfig mqConfig) {
return ApiResult.ok("添加成功", mqConfigService.add(mqConfig));
}
@ApiOperation(value = "修改mq配置")
@PutMapping(value = "update", produces = "application/json;charset=utf-8")
public ApiResult<Boolean> update(MqConfig mqConfig) {
return ApiResult.ok("修改成功", mqConfigService.update(mqConfig));
}
@ApiOperation(value = "删除mq配置")
@DeleteMapping(value = "deleteById", produces = "application/json;charset=utf-8")
public ApiResult<Boolean> deleteById(String[] mqIds) {
return ApiResult.ok("删除成功", mqConfigService.delete(mqIds));
}
}