public class DynamicDataSourceextends AbstractRoutingDataSource{
@Override
protectedObjectdetermineCurrentLookupKey(){
String dataSourceName = DynamicDataSourceContextHolder.getDataSourceName();
return dataSourceName;
}
}
/**
* 动态数据源上下文
*/
public class DynamicDataSourceContextHolder{
private static final ThreadLocal<String> contextHolder = new ThreadLocal<>();
public static List<String> dataSourceNames = new ArrayList<>();
public static void setDataSourceName(String name){
contextHolder.set(name);
}
public staticStringgetDataSourceName(){
return contextHolder.get();
}
public static void clearDataSourceName(){
contextHolder.remove();
}
public static boolean containsDataSource(String dataSourceName){
return dataSourceNames.contains(dataSourceName);
}
}
@Configuration
public class DataSourceConfig{
@Bean(name = "primaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.primary")
@Primary
publicDataSourceprimaryDataSource(){
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@ConfigurationProperties(prefix = "spring.datasource.secondary")
publicDataSourcesecondaryDataSource(){
return DataSourceBuilder.create().build();
}
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@Bean
publicDynamicDataSourcedataSource(){
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put("primaryDataSource", primaryDataSource);
targetDataSources.put("secondaryDataSource", secondaryDataSource);
DynamicDataSourceContextHolder.dataSourceNames.add("primaryDataSource");
DynamicDataSourceContextHolder.dataSourceNames.add("secondaryDataSource");
DynamicDataSource dataSource = new DynamicDataSource();
//设置数据源映射
dataSource.setTargetDataSources(targetDataSources);
//设置默认数据源,当无法映射到数据源时会使用默认数据源
dataSource.setDefaultTargetDataSource(primaryDataSource);
dataSource.afterPropertiesSet();
return dataSource;
}
}
# spring.datasource.primary.jdbcUrl=jdbc:mysql://localhost/test1?useSSL=false spring.datasource.primary.username=root spring.datasource.primary.password=root spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver # spring.datasource.secondary.jdbcUrl=jdbc:mysql://localhost/test2?useSSL=false spring.datasource.secondary.username=root spring.datasource.secondary.password=root spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
/**
* 在方法上使用,用于指定使用哪个数据源
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDataSource {
Stringvalue();
}
@TargetDataSource(value = "primaryDataSource")
publicList<Customer>findAll(){
//TODO
return null;
}
@TargetDataSource(value = "secondaryDataSource")
public void addCustomer(String name, String email){
}
@Aspect
@Component
@Order(-1)// 保证该AOP在@Transactional之前执行
public class DynamicDataSourceChangeAspect{
private static final Logger logger = LoggerFactory.getLogger(DynamicDataSourceChangeAspect.class);
@Before("@annotation(targetDataSource)")
public void changeDataSource(JoinPoint joinPoint, TargetDataSource targetDataSource){
String dsName = targetDataSource.value();
if (!DynamicDataSourceContextHolder.containsDataSource(dsName)) {
System.err.println("数据源[{}]不存在,使用默认数据源 > {}" + targetDataSource.value() + joinPoint.getSignature());
} else {
DynamicDataSourceContextHolder.setDataSourceName(targetDataSource.value()); //设置到动态数据源上下文中
}
}
@After("@annotation(targetDataSource)")
public void restoreDataSource(JoinPoint point, TargetDataSource targetDataSource){
//方法执行完毕之后,销毁当前数据源信息,进行垃圾回收。
DynamicDataSourceContextHolder.clearDataSourceName();
}
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有