下面我们来详细讲解使用dynamic datasource springboot starter实现多数据源及源码分析的完整攻略。
什么是dynamic datasource springboot starter?
dynamic datasource springboot starter是一款基于spring boot的多数据源解决方案,可以支持动态添加和删除数据源,可以方便地生成多数据源的连接池,使用起来非常方便。
使用步骤
1. 添加依赖
在项目的pom.xml文件中添加以下依赖:
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>2.5.2</version>
</dependency>
2. 添加数据源配置
在application.properties或application.yml中添加数据源的配置信息,可以添加多个数据源:
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password=root
spring.datasource.dynamic.datasource.cluster.datasource-class-name=com.alibaba.druid.pool.DruidDataSource
spring.datasource.dynamic.datasource.cluster.url=jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.dynamic.datasource.cluster.username=root
spring.datasource.dynamic.datasource.cluster.password=root
3. 在代码中动态切换数据源
可以使用@DS
注解来动态切换数据源,这里提供两个简单的示例。
示例一:在service层中动态切换数据源
在service层的方法上通过@DS
注解来动态切换数据源。
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@DS("master")
@Override
public List<User> listMaster() {
return userMapper.selectList(null);
}
@DS("cluster")
@Override
public List<User> listCluster() {
return userMapper.selectList(null);
}
}
示例二:在controller层中动态切换数据源
在controller层通过@DS
注解来动态切换数据源。
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/listMaster")
public List<User> listMaster() {
return userService.listMaster();
}
@GetMapping("/listCluster")
public List<User> listCluster() {
return userService.listCluster();
}
}
源码分析
dynamic datasource springboot starter的源码都在Github上,可以自行下载查看。这里简单讲解一下主要的实现原理。
数据源配置处理
首先,在DynamicDataSourceProperties
类中将配置文件中的数据源信息进行解析,并存储在一个Map<String, DataSourceProperty>
中。
@Data
@ConfigurationProperties(prefix = "spring.datasource.dynamic")
public class DynamicDataSourceProperties {
private Map<String, DataSourceProperty> datasource = new HashMap<>();
...
}
动态创建数据源
在DynamicDataSourceProvider
类中,通过反射动态创建数据源,并使用DruidDataSourceWrapper
对数据源进行包装处理,以便能够正确使用Druid的监控处理。
public abstract class DynamicDataSourceProvider {
protected DruidDataSourceWrapper createDataSource(DataSourceProperty dataSourceProperty) {
DruidDataSourceWrapper dsw = DruidDataSourceWrapperBuilder.create()
.type(dataSourceProperty.getType())
.url(dataSourceProperty.getUrl())
.username(dataSourceProperty.getUsername())
.password(dataSourceProperty.getPassword())
.build();
// 数据源监控处理
if (dsw.getDataSource() instanceof DruidDataSource) {
DruidDataSource druidDataSource = (DruidDataSource) dsw.getDataSource();
if (StringUtils.isNotBlank(dataSourceProperty.getFilters())) {
try {
druidDataSource.setFilters(dataSourceProperty.getFilters());
} catch (SQLException e) {
throw new RuntimeException("druid datasource setFilters error", e);
}
}
wallFilter(druidDataSource);
statFilter(druidDataSource);
}
return dsw;
}
...
}
数据源动态切换
在DynamicDataSourceAspect
类中,使用了AOP的思想,通过方法上的@DS
注解来判断当前方法需要使用哪个数据源,然后在方法执行前将当前线程绑定的数据源进行切换。
@Aspect
public class DynamicDataSourceAspect {
....
@Around("@annotation(ds)")
public Object around(ProceedingJoinPoint point, DS ds) throws Throwable {
...
try {
// 切换数据源
DynamicDataSourceContextHolder.setDataSourceLookupKey(ds.value());
// 执行方法
return point.proceed();
} finally {
// 将数据源释放
DynamicDataSourceContextHolder.clearDataSourceLookupKey();
}
}
...
}
以上就是dynamic datasource springboot starter的使用方法和源码分析,希望对大家有所帮助。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:使用dynamic datasource springboot starter实现多数据源及源码分析 - Python技术站