demo地址:https://gitee.com/fhmj520/springboot-datasource.git
1.導(dǎo)入相對應(yīng)的pom文件
<!--aop-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--mybatis plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
2.配置數(shù)據(jù)源鏈接
3.新建DynamicDataSourceConfig
4.新建DynamicDataSource繼承AbstractRoutingDataSource,重寫determineCurrentLookupKey方法實現(xiàn)動態(tài)數(shù)據(jù)源
需要理解ThreadLocal仰冠,線程的局部變量,相當(dāng)于private static,供本線程內(nèi)存儲內(nèi)容
在DynamicDataSource中重寫構(gòu)造方法,在決定數(shù)據(jù)源前把數(shù)據(jù)源信息初始化完成并配置好
5.設(shè)定多數(shù)據(jù)源的Names
新建DataSourceNames
public interface DataSourceNames {
String FIRST = "first";
String SECOND = "second";
}
6.需要啟動時初始化數(shù)據(jù)源信息,完成后面事務(wù)的初始化需要的依賴數(shù)據(jù)源Bean
所以在DynamicDataSourceConfig中進行配置
/**
* 由于數(shù)據(jù)源的信息需要在初始化的時候加載啟動
* @param firstDataSource
* @param secondDataSource
* @return
*/
@Bean
@Primary //優(yōu)先考慮,優(yōu)先考慮被注解的對象的注入
public DynamicDataSource dataSource(DataSource firstDataSource,
DataSource secondDataSource){
Map<Object,Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceNames.FIRST,firstDataSource);
targetDataSources.put(DataSourceNames.SECOND,secondDataSource);
return new DynamicDataSource(firstDataSource,targetDataSources);
}
7.編寫多數(shù)據(jù)源的切面處理類和注解
AOP類
/**
* 多數(shù)據(jù)源,切面處理類
*/
@Aspect
@Component
public class DataSourceAspect implements Ordered {
protected Logger logger = LoggerFactory.getLogger(getClass());
@Pointcut("@annotation(com.example.datasource.DataSource)")
public void dataSourcePointCut(){}
@Around("dataSourcePointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSource ds = method.getAnnotation(DataSource.class);
if(ds == null){
DynamicDataSource.setDataSource(DataSourceNames.FIRST);
logger.debug("set datasource is " + DataSourceNames.FIRST);
}else {
DynamicDataSource.setDataSource(ds.name());
logger.debug("set datasource is " + ds.name());
}
try {
return point.proceed();
} finally {
DynamicDataSource.clearDataSource();
logger.debug("clean datasource");
}
}
@Override
public int getOrder() {
return 1;
}
}
DataSource注解
8.使用
在業(yè)務(wù)實現(xiàn)中進行注解調(diào)用的數(shù)據(jù)庫缚去,進行多數(shù)據(jù)源的切換,不涉及多事務(wù)