基于若依微服务的多数据源改造
一步完成即可
若依微服务本身只提供注解的方式进行多数据源,而如果需要实现SASS方式进行多数据动态调整,根据每个租户自己的域名进行数据源的动态切换,需要再完成如下几步:
- 一、ruoyi-gateway需要AuthFilter中解析域名并把二级域名放到请求头中
//此处为记录并设置当前二级域名,从而进行租户的区分
HttpHeaders headers = request.getHeaders();
if (headers.containsKey(REFERER)) {
List<String> domains = headers.get(REFERER);
if (domains != null && !domains.isEmpty()){
String tenentCode = getDomainForUrl(domains.get(0));
if (StringUtils.equals(tenentCode,LOCALHOST)||
isNum(tenentCode)
) {
tenentCode = SecurityConstants.MASTER;
}
addHeader(mutate, SecurityConstants.TENANT_CODE, tenentCode);
}
}
-
2、ruoyi-common-security处理请求头数据
-
SecurityContextHolder.setTenantCode(ServletUtils.getHeader(request, SecurityConstants.TENANT_CODE));
-
3、ruoyi-common-datasource
-
此项目默认只有两个注解改造成如下即可
-
代码我就不解释了,很容易理解,一句话,根据nacos中的yml配置文件主动刷新加载所有数据源,根据determineCurrentLookupKey方法切换即可
/**
* @author XIAOWENHUI
*/
@Slf4j
public class EduDynamicDataSource extends AbstractRoutingDataSource {
/**
* 每次连接数据库,都会去设置数据源
* @return
*/
@Override
public Object determineCurrentLookupKey() {
return SecurityContextHolder.getTenantCode();
}
}
/**
* @author XIAOWENHUI
*/
public class EduDynamicDataSourceProperties extends DynamicDataSourceProperties {
}
/**
* @author XIAOWENHUI
*
* 多数据源配置
*/
@Slf4j
@RefreshScope
@DependsOn("dynamicDataSourceProperties")
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = DynamicDataSourceProperties.PREFIX, name = "enabled", havingValue = "true", matchIfMissing = true)
public class EduDynamicDataSourceConfig {
@Autowired
private DynamicDataSourceProperties properties;
@Bean
@RefreshScope
@ConditionalOnMissingBean
public DynamicDataSourceProvider dynamicDataSourceProvider() {
Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
return new YmlDynamicDataSourceProvider(datasourceMap);
}
@RefreshScope
@ConditionalOnMissingBean
public DataSource dataSource(DynamicDataSourceProvider dynamicDataSourceProvider) throws Exception {
DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
dataSource.setPrimary(properties.getPrimary());
dataSource.setStrict(properties.getStrict());
dataSource.setStrategy(properties.getStrategy());
dataSource.setP6spy(properties.getP6spy());
dataSource.setSeata(properties.getSeata());
dataSource.afterPropertiesSet();
return dataSource;
}
}
/**
* @author XIAOWENHUI
*/
@RefreshScope
@Configuration(proxyBeanMethods = false)
public class EduDynamicPropertiesConfig {
@RefreshScope
@Bean("dynamicDataSourceProperties")
@Primary
@ConditionalOnMissingBean
public DynamicDataSourceProperties dynamicDataSourceProperties() {
return new EduDynamicDataSourceProperties();
}
}
有不清楚的地方,欢迎大家留言。