针对微服务架构中常用的设计模块,通常我们都会需要使用到druid作为我们的数据连接池,当架构发生扩展的时候 ,通常面对的数据存储服务器也会渐渐增加,从原本的单库架构逐渐扩展为复杂的多库架构。
当在业务层需要涉及到查询多种同数据库的场景下,我们通常需要在执行sql的时候动态指定对应的datasource。
而Spring的AbstractRoutingDataSource则正好为我们提供了这一功能点,下边我将通过一个简单的基于springboot+aop的案例来实现如何通过自定义注解切换不同的数据源进行读数据操作,同时也将结合部分源码的内容进行讲解。
首先我们需要自定义一个专门用于申明当前java应用程序所需要使用到哪些数据源信息:
packagemutidatasource.annotation;importmutidatasource.config.DataSourceConfigRegister;importmutidatasource.enums.SupportDatasourceEnum;importorg.springframework.context.annotation.Import;importorg.springframework.stereotype.Component;import java.lang.annotation.*;/*** 注入数据源
*
*@authoridea
* @data 2020/3/7*/@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(DataSourceConfigRegister.class)public @interfaceAppDataSource {
SupportDatasourceEnum[] datasourceType();
}
这里为了方便,我将测试中使用的数据源地址都配置在来enum里面,如果后边需要灵活处理的话,可以将这些配置信息抽取出来放在一些配置中心上边。
packagemutidatasource.enums;importlombok.AllArgsConstructor;importlombok.Getter;importlombok.NoArgsConstructor;/*** 目前支持的数据源信息
*
*@authoridea
* @data 2020/3/7*/@AllArgsConstructor
@Getterpublic enumSupportDatasourceEnum {
PROD_DB("jdbc:mysql://localhost:3306/db-prod?useUnicode=true&characterEncoding=utf8","root","root","db-prod"),
DEV_DB("jdbc:mysql://localhost:3306/db-dev?useUnicode=true&characterEncoding=utf8","root","root","db-dev"),
PRE_DB("jdbc:mysql://localhost:3306/db-pre?useUnicode=true&characterEncoding=utf8","root","root","db-pre");
String url;
String username;
String password;
String databaseName;
@OverridepublicString toString() {return super.toString().toLowerCase();
}
}
之所以要创建这个@AppDataSource注解,是要在springboot的启动类上边进行标注:
packagemutidatasource;importmutidatasource.annotation.AppDataSource;importmutidatasource.enums.SupportDatasourceEnum;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;/***@authoridea
* @data 2020/3/7*/@SpringBootApplication
@AppDataSource(datasourceType={SupportDatasourceEnum.DEV_DB, SupportDatasourceEnum.PRE_DB, SupportDatasourceEnum.PROD_DB})public classSpringApplicationDemo {public static voidmain(String[] args) {
SpringApplication.run(SpringApplicationDemo.class);
}
}
借助springboot的ImportSelector 自定义一个注册器来获取启动类头部的注解所指定的数据源类型&#x