matrix.boot.jdbc.config.ShardingJdbcDataSourceAutoConfiguration Maven / Gradle / Ivy
The newest version!
package matrix.boot.jdbc.config;
import lombok.extern.slf4j.Slf4j;
import matrix.boot.common.exception.ServiceException;
import matrix.boot.common.utils.AssertUtil;
import matrix.boot.common.utils.ReflectUtil;
import matrix.boot.common.utils.StringUtil;
import matrix.boot.jdbc.beans.MoreDataSource;
import matrix.boot.jdbc.enums.ShardingType;
import matrix.boot.jdbc.properties.JdbcProperties;
import matrix.boot.jdbc.properties.ShardingProperties;
import org.apache.shardingsphere.api.config.masterslave.LoadBalanceStrategyConfiguration;
import org.apache.shardingsphere.api.config.masterslave.MasterSlaveRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.*;
import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.hint.HintShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
import org.apache.shardingsphere.api.sharding.standard.RangeShardingAlgorithm;
import org.apache.shardingsphere.shardingjdbc.api.MasterSlaveDataSourceFactory;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.apache.shardingsphere.shardingjdbc.jdbc.core.datasource.ShardingDataSource;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionTypeHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.core.PriorityOrdered;
import org.springframework.util.CollectionUtils;
import javax.sql.DataSource;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.*;
/**
* shardingJdbc自动装配
*
* @author wangcheng
* 2021/8/17
**/
@EnableConfigurationProperties({JdbcProperties.class, ShardingProperties.class,
ShardingProperties.ShardingRule.class, ShardingProperties.MasterSlaveRule.class})
@ConditionalOnExpression("${matrix.jdbc.enabled} && '${matrix.jdbc.init-type}'.equals('ShardingJdbc')")
@Slf4j
public class ShardingJdbcDataSourceAutoConfiguration {
/**
* 主从规则
*
* @param jdbcProperties jdbc配置
* @param moreDataSource 多数据源
* @return 主从规则
*/
@Bean
@ConditionalOnExpression("'${matrix.jdbc.sharding.type}'.equals('MasterSlave')")
@ConditionalOnMissingBean
public MasterSlaveRuleConfiguration masterSlaveRuleConfiguration(JdbcProperties jdbcProperties, MoreDataSource moreDataSource) {
//获取用户配置的规则
ShardingProperties sharding = jdbcProperties.getSharding();
//主从规则
Map dataSourceMap = moreDataSource.getDataSourceMap();
//获取迭代器
Iterator> iterator = dataSourceMap.entrySet().iterator();
String masterDbKey = iterator.next().getKey();
List slaveDbKey = new ArrayList<>();
while (iterator.hasNext()) {
slaveDbKey.add(iterator.next().getKey());
}
if (sharding.getMasterSlaveRule() != null && !StringUtil.isEmpty(sharding.getMasterSlaveRule().getLoadBalanceAlgorithmType())) {
//读取负载均衡策略
LoadBalanceStrategyConfiguration loadBalanceStrategyConfiguration = new LoadBalanceStrategyConfiguration(sharding.getMasterSlaveRule().getLoadBalanceAlgorithmType());
return new MasterSlaveRuleConfiguration(masterDbKey, masterDbKey, slaveDbKey, loadBalanceStrategyConfiguration);
} else {
return new MasterSlaveRuleConfiguration(masterDbKey, masterDbKey, slaveDbKey);
}
}
/**
* 分片规则
*
* @param jdbcProperties jdbc配置
* @return 分片规则
*/
@Bean
@ConditionalOnExpression("'${matrix.jdbc.sharding.type}'.equals('Sharding')")
@ConditionalOnMissingBean
public ShardingRuleConfiguration shardingRuleConfiguration(JdbcProperties jdbcProperties) {
//获取用户配置的规则
ShardingProperties sharding = jdbcProperties.getSharding();
//创建分片规则
ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
AssertUtil.notNullTip(sharding.getShardingRule(), "matrix.jdbc.sharding.sharding-rule");
if (!CollectionUtils.isEmpty(sharding.getShardingRule().getTables())) {
sharding.getShardingRule().getTables().forEach((tableName, table) -> {
//创建表分片规则
TableRuleConfiguration tableRuleConfiguration = new TableRuleConfiguration(tableName, table.getActualDataNodes());
//数据库策略
tableRuleConfiguration.setDatabaseShardingStrategyConfig(parseShardingStrategyConfiguration(table.getDatabaseShardingStrategy()));
//表策略
tableRuleConfiguration.setTableShardingStrategyConfig(parseShardingStrategyConfiguration(table.getTableShardingStrategy()));
//设置主键生成策略
if (table.getKeyGeneratorStrategy() != null) {
tableRuleConfiguration.setKeyGeneratorConfig(parseKeyGeneratorConfiguration(table.getKeyGeneratorStrategy()));
}
//加入到分片规则中
shardingRuleConfig.getTableRuleConfigs().add(tableRuleConfiguration);
});
}
//设置绑定表规则
if (!CollectionUtils.isEmpty(sharding.getShardingRule().getBindingTables())) {
shardingRuleConfig.setBindingTableGroups(sharding.getShardingRule().getBindingTables());
}
//设置广播表规则
if (!CollectionUtils.isEmpty(sharding.getShardingRule().getBroadcastTables())) {
shardingRuleConfig.setBroadcastTables(sharding.getShardingRule().getBroadcastTables());
}
//设置默认库分片策略
if (sharding.getShardingRule().getDefaultDatabaseStrategy() != null) {
shardingRuleConfig.setDefaultDatabaseShardingStrategyConfig(parseShardingStrategyConfiguration(sharding.getShardingRule().getDefaultDatabaseStrategy()));
}
//设置默认表分片策略
if (sharding.getShardingRule().getDefaultTableStrategy() != null) {
shardingRuleConfig.setDefaultTableShardingStrategyConfig(parseShardingStrategyConfiguration(sharding.getShardingRule().getDefaultTableStrategy()));
}
//设置默认主键生成策略
if (sharding.getShardingRule().getDefaultKeyGeneratorStrategy() != null) {
shardingRuleConfig.setDefaultKeyGeneratorConfig(parseKeyGeneratorConfiguration(sharding.getShardingRule().getDefaultKeyGeneratorStrategy()));
}
return shardingRuleConfig;
}
/**
* 数据源
*
* @param moreDataSource 多数据源
* @param jdbcProperties jdbc配置
* @param beanFactory bean工厂
* @return 数据源
*/
@Bean
public DataSource dataSource(MoreDataSource moreDataSource, JdbcProperties jdbcProperties, ConfigurableBeanFactory beanFactory) throws SQLException {
//获取用户配置的规则
ShardingProperties sharding = jdbcProperties.getSharding();
AssertUtil.notNullTip(sharding, "matrix.jdbc.sharding");
ShardingType ruleType = ShardingType.getByCode(sharding.getType());
//属性配置
Properties properties = new Properties();
if (sharding.isShowSql()) {
properties.put("sql.show", true);
}
if (sharding.getExecutorSize() != null) {
properties.put("executor.size", sharding.getExecutorSize());
}
log.info("ShardingJdbcDataSource init success!");
//创建数据源
if (ShardingType.MasterSlave.equals(ruleType)) {
return MasterSlaveDataSourceFactory.createDataSource(moreDataSource.getDataSourceMap(), beanFactory.getBean(MasterSlaveRuleConfiguration.class), properties);
} else if (ShardingType.Sharding.equals(ruleType)) {
return ShardingDataSourceFactory.createDataSource(moreDataSource.getDataSourceMap(), beanFactory.getBean(ShardingRuleConfiguration.class), properties);
}
throw new ServiceException("not impl ShardingRuleType for " + ruleType.getCode());
}
/**
* 分片策略解析
*
* @param shardingStrategy 策略配置
* @return 分片策略
*/
private ShardingStrategyConfiguration parseShardingStrategyConfiguration(ShardingProperties.ShardingStrategy shardingStrategy) {
if (shardingStrategy == null) {
return new NoneShardingStrategyConfiguration();
}
if (shardingStrategy.getStandard() != null) {
if (shardingStrategy.getStandard().getRangeAlgorithmClass() == null) {
return new StandardShardingStrategyConfiguration(shardingStrategy.getStandard().getShardingColumn(),
ReflectUtil.newInstance(shardingStrategy.getStandard().getPreciseAlgorithmClass()));
} else {
return new StandardShardingStrategyConfiguration(shardingStrategy.getStandard().getShardingColumn(),
ReflectUtil.newInstance(shardingStrategy.getStandard().getPreciseAlgorithmClass()),
ReflectUtil.newInstance(shardingStrategy.getStandard().getRangeAlgorithmClass()));
}
}
if (shardingStrategy.getComplex() != null) {
return new ComplexShardingStrategyConfiguration(shardingStrategy.getComplex().getShardingColumn(),
ReflectUtil.newInstance(shardingStrategy.getComplex().getAlgorithmClass()));
}
if (shardingStrategy.getInline() != null) {
ShardingProperties.InlineStrategy inlineStrategy = shardingStrategy.getInline();
return new InlineShardingStrategyConfiguration(inlineStrategy.getShardingColumn(), inlineStrategy.getAlgorithmExpression());
}
if (shardingStrategy.getHint() != null) {
return new HintShardingStrategyConfiguration(ReflectUtil.newInstance(shardingStrategy.getHint().getAlgorithmClass()));
}
return new NoneShardingStrategyConfiguration();
}
/**
* 解析主键生成策略
*
* @param keyGeneratorStrategy 主键生成策略属性
* @return 主键生成策略
*/
private KeyGeneratorConfiguration parseKeyGeneratorConfiguration(ShardingProperties.KeyGeneratorStrategy keyGeneratorStrategy) {
return new KeyGeneratorConfiguration(keyGeneratorStrategy.getType(), keyGeneratorStrategy.getColumn(), (Properties) keyGeneratorStrategy.getProps());
}
}