当前位置: 首页 > news >正文

【springboot组件开发】三方中间件自定义自动装载(rabbitmq/rocketmq/cmq)

文章目录

  • 需求背景
  • 案例说明
  • 实现方案

需求背景

由于目前公司项目是面向政企单位,所以项目部署方案采用了私有云模式,而每个地区的客户要求的中间件存在差异,为了实现基础框架和业务代码的复用,需要实现一套基础框架同时引入多个同类型的中间件,基于配置实现底层组件切换,并且禁用未开启组件的自启动

案例说明

这里以MQ为例,我们同时引入rabbitmq、rocketmq和cmq,基于配置framework.mq.rocketmq.type实现不同mq的切换,默认使用rabbitmq,切换时只有启用类型的mq才会触发自动装配连接和健康检查

备注:如果只是单纯同时引入多个组件依赖,项目启动阶段未配置连接资源的组件会提示连接异常或者类装载冲突
在这里插入图片描述

实现方案

1.以starter组件形式定义组件,通过spring.factories声明组件初始化对象和配置文件,这里不详细描述
在这里插入图片描述
2.在starter内引入rabbitmq、rocketmq和cmq的starter依赖

<!-- cmq -->
<dependency><groupId>com.bosssoft.gp</groupId><artifactId>starter-gp-stream-client</artifactId><version>V5.0.7.4.Release</version>
</dependency>
<!-- rabbit-mq -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-amqp</artifactId>
</dependency>
<!-- rocketmq-mq -->
<dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.3.2</version>
</dependency>

3.在组件内排除掉rabbitmq、rocketmq和cmq的AutoConfiguration对象,这样在spring容器加载时就不会自启动对应组件,也不会在项目启动阶段去连接对应mq(cmq采用手动创建监听器,不会触发自启动可以不处理)
3.1.可以在starter内通过yml文件声明:

spring:autoconfigure:exclude: org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration

3.2.也可以通过@EnableAutoConfiguration的exclude实现排包

import org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration;
import org.springframework.context.annotation.Configuration;
/*** @author: xielijie* @className: MqConfig* @description:这里独立配置是因为其他config类都被spring.factories声明,添加@EnableAutoConfiguration会提示异常* @date: 2025-03-07 14:31**/
@Configuration
@Configuration
//#在配置中把默认的RabbitMQ/RocketMQ自动配置类排除掉, 再通过自定义配置开关控制装载RabbitMQ/RocketMQ, 实现rabbitMq/RocketMQ自动装配自定义开关
@EnableAutoConfiguration(exclude = {RabbitAutoConfiguration.class, RocketMQAutoConfiguration.class, MqClientConfiguration.class})
public class MqExcludeAutoConfiguration {}

3.3.这里延伸个场景,有部分三方组件,比如tomcat,由于配置加载优先级较高,导致在自定义的starter组件内用exclude属性排包太晚加载导致排包不生效(直接在项目的application内声明是有效的,但是组件化声明失效),可以采用自定义配置并且优先加载的方案

@Configuration
@PropertySource(value = "classpath:application-web.yml",encoding = "utf-8",factory = DefaultConfigFactory.class)
@ComponentScan(basePackages = {"com.bosssoft.gpmscloud"})
@Slf4j
public class GpmsCloudWebMvcAutoConfiguration implements EnvironmentPostProcessor {@Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {MutablePropertySources propertySources = environment.getPropertySources();Map<String, Object> properties = new HashMap<>();properties.put("spring.autoconfigure.exclude","org.apache.rocketmq.spring.autoconfigure.RocketMQAutoConfiguration,com.bosssoft.gp.stream.client.starter.MqClientConfiguration,com.bosssoft.gp.stream.client.starter.MqClientConfiguration");// 添加到属性源中,优先级设置为较高MapPropertySource propertySource = new MapPropertySource("mqContainerExcludeProperties", properties);propertySources.addFirst(propertySource);}}

4.基于配置动态加载mq实现
rabbitmq,默认开启

@Configuration
@ConditionalOnProperty(prefix = "framework.mq", name = "type", havingValue = "rabbitmq", matchIfMissing = true)
public class CustomRabbitAutoConfiguration extends RabbitAutoConfiguration {}

rocketmq

@Configuration
@ConditionalOnProperty(prefix = "framework.mq", name = "type", havingValue = "rabbitmq")
public class CustomRocketAutoConfiguration extends RocketMQAutoConfiguration {public CustomRocketAutoConfiguration(Environment environment) {super(environment);}
}

cmq

@Configuration
@ConditionalOnProperty(prefix = "framework.mq", name = "type", havingValue = "cmq")
public class CustomCmqAutoConfiguration extends MqClientConfiguration {}

5.发送和监听器业务代码需要基于配置加载
ps:
在这里插入图片描述
6.业务使用
以此,业务服务在引入我们自定义的framework-starter-mq模块后,就可以通过framework.mq.rocketmq.type配置来切换不同的mq组件,业务模块对于mq的消费和发生可以根据@ConditionalOnProperty(prefix = “framework.mq.xxx”, name = “enabled”, havingValue = “true”)来实现实现切换
其他同类型三方组件接入也可以采用该思路来实现自定义的动态加载组件

http://www.xdnf.cn/news/1001557.html

相关文章:

  • 记录一次jenkins slave因为本地安装多个java版本导致的问题
  • stm32f103 标准库移植rt-thread nano
  • 学习笔记整理之状态图与状态图搜索
  • Windows 提权工具(“Potato“ 系列)用法指南
  • 火线、零线、地线 基础知识
  • 实现图片懒加载
  • 大话软工笔记—架构的概要设计
  • 【AS32系列MCU调试教程】基础配置:Eclipse项目与工具链的优化
  • SD-WAN优化云应用与多云架构访问的关键策略
  • 408考研逐题详解:2009年第39题
  • 深入探索IIC-OLED显示技术:嵌入式仿真平台如何重塑高校教学范式——深圳航天科技创新研究院技术赋能新一代工程教育
  • 观点 | 科技企业到了品牌建设的历史性窗口期
  • 界面开发框架DevExpress XAF实践:集成.NET Aspire后如何实现服务安排?
  • Kratos 与Golang Cms的关系
  • 深度学习环境搭建(pycharm+yolov5)
  • 【AWS入门】IAM多重身份验证(MFA)简介
  • 深度解析Git错误:`fatal: detected dubious ownership in repository` 的根源与解决方案
  • OpenAI API:LLM编程的事实标准(上)
  • R语言缓释制剂QBD解决方案之五
  • GitLab 拉取变慢的原因及排查方法
  • UE5 学习系列(九)光照系统介绍
  • linux中的locate命令
  • Vue3+TypeScript实现状态模式
  • cuda编程笔记(3)--常量内存与事件
  • 嘉立创EDA初识
  • 外资车全面反弹,被看衰的日系车尤其凶猛,国产电车再承压
  • 智慧园区可视化怎么做?
  • 快速排序优化技巧详解:提升性能的关键策略
  • Python爬虫实战:研究AutobahnPython相关技术
  • 股指期货为什么会出现贴水现象?