All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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());
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy