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

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读取
    }
}

http://www.kler.cn/a/590968.html

相关文章:

  • 超详细kubernetes部署k8s----一台master和两台node
  • AK 接口
  • Oracle静默安装方法
  • MySQL事务:确保数据一致性的关键机制
  • 复旦:LLM不同层位置编码缩放
  • 【arXiv 2025】卷积加法自注意力CASAtt,轻量且高效,即插即用!
  • 【紫光同创FPGA开发常用工具】FPGACPLD的下载与固化
  • 数据库设计实验(4)—— 数据更新实验
  • 神思智飞无人机智能调度系统介绍
  • pwn刷题记录
  • 笔记:代码随想录算法训练营day56:图论理论基础、深搜理论基础、98. 所有可达路径、广搜理论基础
  • XXXX数字化交流BI系统分析与设计(40页PPT)(文末有下载方式)
  • Web 小项目: 网页版图书管理系统
  • ESMFold 安装教程
  • (6)用于无GPS导航的Nooploop
  • 音视频处理的“瑞士军刀”与“积木”:FFmpeg 与 GStreamer 的深度揭秘
  • leetcode236-二叉树的公共祖先
  • Django REST Framework中的序列化器类和视图类
  • 基于深度学习的OCR+NLP,医疗化验单智能识别方案
  • MPC算法路径跟踪_Matlab实现