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

AOP+Nacos实现动态数据源切换

1. 添加依赖
<!-- Nacos配置中心 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    <version>2022.0.0.0</version>
</dependency>
<!-- 动态数据源(支持多数据源切换) -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>4.2.0</version>
</dependency>
2. 配置Nacos连接

bootstrap.yml中配置Nacos服务地址及数据源配置文件:

spring:
  application:
    name: dynamic-datasource-demo
  cloud:
    nacos:
      config:
        server-addr: 127.0.0.1:8848
        group: DEFAULT_GROUP
        # 数据源配置文件ID(需在Nacos控制台提前创建)
        data-id: datasource-config.yaml
        file-extension: yaml
        refresh-enabled: true # 开启动态刷新
3. Nacos配置内容

在Nacos控制台创建datasource-config.yaml文件,内容如下:

datasource:
  dynamic:
    primary: master # 默认数据源
    datasource:
      master:
        url: jdbc:mysql://127.0.0.1:3306/master?useSSL=false
        username: root
        password: 123456
        driver-class-name: com.mysql.cj.jdbc.Driver
      slave1:
        url: jdbc:mysql://127.0.0.1:3306/slave1?useSSL=false
        username: root
        password: 123456
        driver-class-name: com.mysql.cj.jdbc.Driver
4. 动态数据源配置类
@Configuration
@Slf4j
public class DynamicDataSourceConfig {
    
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.dynamic")
    public DataSource dynamicDataSource() {
        // 自动读取Nacos配置中的datasource节点
        return new DynamicRoutingDataSource();
    }

    // 监听Nacos配置变更,刷新数据源
    @NacosConfigListener(dataId = "datasource-config.yaml", groupId = "DEFAULT_GROUP")
    public void onConfigChanged(String newConfig) {
        log.info("检测到数据源配置变更:{}", newConfig);
        DynamicDataSourceContextHolder.clear();
        DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dynamicDataSource();
        ds.reload(); // 核心:触发数据源重载
    }
}
5. 数据源上下文管理器
public class DynamicDataSourceContextHolder {
    private static final ThreadLocal<String> CONTEXT = new ThreadLocal<>();
    
    public static void setDataSourceKey(String key) {
        CONTEXT.set(key);
    }
    
    public static String getDataSourceKey() {
        return CONTEXT.get();
    }
    
    public static void clear() {
        CONTEXT.remove();
    }
}
6. 动态切换实现(AOP切面)
@Aspect
@Component
public class DataSourceAspect {
    
    @Pointcut("@annotation(com.example.annotation.DS)")
    public void dataSourcePointCut() {}
    
    @Around("dataSourcePointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        DS ds = signature.getMethod().getAnnotation(DS.class);
        String oldKey = DynamicDataSourceContextHolder.getDataSourceKey();
        DynamicDataSourceContextHolder.setDataSourceKey(ds.value());
        try {
            return joinPoint.proceed();
        } finally {
            DynamicDataSourceContextHolder.setDataSourceKey(oldKey);
        }
    }
}
7. 自定义注解@DS
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DS {
    String value() default "master";
}
8. Service层使用示例
@Service
public class UserServiceImpl implements UserService {
    
    @Autowired
    private UserMapper userMapper;
    
    @DS("master")
    public void insert(User user) {
        userMapper.insert(user); // 写入主库
    }
    
    @DS("slave1")
    public User getById(Long id) {
        return userMapper.selectById(id); // 从slave1读取
    }
}

相关文章:

  • 企业级云MES全套源码,支持app、小程序、H5、台后管理端
  • 【AI】在AWS AI芯片服务上部署运行Qwen 2.5模型
  • 科技云报到:AI Agent打了个响指,商业齿轮加速转动
  • Android 第四次面试总结(自定义 View 与事件分发深度解析)
  • pytorch小记(十):pytorch中torch.tril 和 torch.triu 详解
  • 一场由 ES 分片 routing 引发的问题
  • 【含文档+PPT+源码】基于小程序的智能停车管理系统设计与开发
  • 【数据分享】1999—2023年地级市固定资产投资和对外经济贸易数据(Shp/Excel格式)
  • 咖啡点单小程序毕业设计(JAVA+SpringBoot+微信小程序+完整源码+论文)
  • 卷积神经网络(CNN)与反向传播
  • 威联通 NAS 的 Docker 镜像与安装 logseq
  • 案例驱动的 IT 团队管理:创新与突破之路:第三章 项目攻坚:从流程优化到敏捷破局-3.2.3技术债务的可视化管理方案
  • 永磁同步电机模型第二篇之两相电机实时模型
  • 使用 ESP8266 和 Android 应用程序实现基于 IOT 的语音控制家庭自动化
  • Apache DolphinScheduler:一个可视化大数据工作流调度平台
  • VSTO(C#)Excel开发13:实现定时器
  • Search after解决ES深度分页问题
  • Modbus通信协议基础知识总结
  • 003-掌控命令行-CLI11-C++开源库108杰
  • 音频大语言模型可作为描述性语音质量评价器
  • 中国驻美国使领馆提醒在美中国公民注意交通安全
  • 5月1日,多位省级党委书记调研旅游市场、假期安全等情况
  • 多地景区发公告称售票达接待峰值,有景区暂停网络和线下售票
  • “国宝探索记”增强亲子连接,国宝成了生活想象的一部分
  • 空间站第八批科学实验样品返抵地球并交付科学家
  • 解放日报:持续拿出排头兵姿态先行者担当