在Spring Boot中配置動態數據源需要以下步驟:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.9.0</version>
</dependency>
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
@Primary
public DynamicDataSource dataSource(DataSource masterDataSource, DataSource slaveDataSource) {
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("master", masterDataSource);
targetDataSources.put("slave", slaveDataSource);
DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSources);
dataSource.setDefaultTargetDataSource(masterDataSource);
return dataSource;
}
}
# 主數據源配置
spring.datasource.master.url = jdbc:mysql://localhost:3306/master_database
spring.datasource.master.username = root
spring.datasource.master.password = root
# 從數據源配置
spring.datasource.slave.url = jdbc:mysql://localhost:3306/slave_database
spring.datasource.slave.username = root
spring.datasource.slave.password = root
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}
public class DataSourceContextHolder {
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
public static void setDataSource(String dataSource) {
CONTEXT_HOLDER.set(dataSource);
}
public static String getDataSource() {
return CONTEXT_HOLDER.get();
}
public static void clearDataSource() {
CONTEXT_HOLDER.remove();
}
}
@Aspect
@Component
public class AopDataSourceAspect {
@Before("@annotation(com.example.dynamicdatasource.annotation.DataSource)")
public void switchDataSource(JoinPoint point) {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = signature.getMethod();
DataSource dataSource = method.getAnnotation(DataSource.class);
if (dataSource == null) {
DataSourceContextHolder.setDataSource("master");
} else {
DataSourceContextHolder.setDataSource(dataSource.value());
}
}
@After("@annotation(com.example.dynamicdatasource.annotation.DataSource)")
public void restoreDataSource(JoinPoint point) {
DataSourceContextHolder.clearDataSource();
}
}
@DataSource
注解,如:@DataSource("slave")
public List<User> getUsers() {
// 查詢從數據源
}
通過以上配置,就可以在Spring Boot中實現動態數據源的切換。