解析配置文件自动装配 DataSource + AbstractRoutingDataSource + AOP 实现动态数据源 下:配置动态数据源,AOP 进行使用

上篇文章中已经借助 DynamicDataSourceBuilder 类从配置文件中解析得到了默认数据源和动态数据源,接下来需要配置动态数据源的“本体”,并借助 AOP 动态的切换数据源。

配置动态数据源

AbstractRoutingDataSource 实现了 InitializingBean 接口,在 afterPropertiesSet方法中通过处理 targetDataSourcesdefaultTargetDataSource中得到最终的 resolvedDefaultDataSourceresolvedDataSources,我们的实现类(动态数据源“本体”)需要覆写该方法,从而给targetDataSourcesdefaultTargetDataSource进行赋值。
image.png
可以看到第 118 行如果 targetDataSources 为 null 就会抛出异常,因此我们的导出类需要先进行赋值,再调用父类方法,动态数据源配置代码如下:

@Component
public class DynamicDataSource extends AbstractRoutingDataSource {
   

    private static final ThreadLocal<DsKey> dataSourceKey = new InheritableThreadLocal<DsKey>() {
   
        @Override
        protected DsKey initialValue() {
   
            return DsKey.DATASOURCE;
        }
    };
    @Autowired
    private DynamicDataSourceBuilder dynamicDataSourceBuilder;

    // 维护数据源 key(Lookup key)
    private static
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用AbstractRoutingDataSource可以很方便地配置数据源,具体步骤如下: 1.自定义动态数据源类DynamicDataSource,继承AbstractRoutingDataSource类,并实现determineCurrentLookupKey()方法,该方法返回当前数据源的key值。 2.在Spring配置文件配置多个数据源,并将DynamicDataSource作为默认数据源。 3.使用AOP技术,在方法执行前动态切换数据源。 下面是一个简单的示例: ```java // 自定义动态数据源类 public class DynamicDataSource extends AbstractRoutingDataSource { @Override protected Object determineCurrentLookupKey() { return DbContextHolder.getDataSource(); } } // 数据源上下文,用于存储当前线程使用数据源key值 public class DbContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); public static void setDataSource(String dataSource) { contextHolder.set(dataSource); } public static String getDataSource() { return contextHolder.get(); } public static void clearDataSource() { contextHolder.remove(); } } // 配置多个数据源 @Bean(name = "dataSource1") public DataSource dataSource1() { // ... } @Bean(name = "dataSource2") public DataSource dataSource2() { // ... } @Bean(name = "dynamicDataSource") public DynamicDataSource dynamicDataSource() { DynamicDataSource dataSource = new DynamicDataSource(); Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put("dataSource1", dataSource1()); targetDataSources.put("dataSource2", dataSource2()); dataSource.setTargetDataSources(targetDataSources); dataSource.setDefaultTargetDataSource(dataSource1()); return dataSource; } // 使用AOP动态切换数据源 @Aspect @Component public class DataSourceAspect { @Pointcut("@annotation(com.gnxk.datasource.annotation.DataSource)") public void dataSourcePointCut() { } @Before("dataSourcePointCut()") public void before(JoinPoint joinPoint) { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); DataSource dataSource = signature.getMethod().getAnnotation(DataSource.class); if (dataSource == null) { DbContextHolder.setDataSource("dataSource1"); } else { DbContextHolder.setDataSource(dataSource.value()); } } @After("dataSourcePointCut()") public void after(JoinPoint joinPoint) { DbContextHolder.clearDataSource(); } } ``` 使用注解@DataSource("dataSource1")或@DataSource("dataSource2")来指定使用哪个数据源

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值