专栏首页码匠的流水账聊聊sharding-jdbc的AbstractDataSourceAdapter
原创

聊聊sharding-jdbc的AbstractDataSourceAdapter

本文主要研究一下sharding-jdbc的AbstractDataSourceAdapter

AbstractUnsupportedOperationDataSource

incubator-shardingsphere-4.0.0-RC1/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/unsupported/AbstractUnsupportedOperationDataSource.java

public abstract class AbstractUnsupportedOperationDataSource extends WrapperAdapter implements DataSource {
    
    @Override
    public final int getLoginTimeout() throws SQLException {
        throw new SQLFeatureNotSupportedException("unsupported getLoginTimeout()");
    }
    
    @Override
    public final void setLoginTimeout(final int seconds) throws SQLException {
        throw new SQLFeatureNotSupportedException("unsupported setLoginTimeout(int seconds)");
    }
}
  • AbstractUnsupportedOperationDataSource继承了WrapperAdapter,声明实现javax.sql.DataSource接口,其覆盖了getLoginTimeout、setLoginTimeout方法,抛出SQLFeatureNotSupportedException异常

AbstractDataSourceAdapter

incubator-shardingsphere-4.0.0-RC1/sharding-jdbc/sharding-jdbc-core/src/main/java/org/apache/shardingsphere/shardingjdbc/jdbc/adapter/AbstractDataSourceAdapter.java

@Getter
@Setter
public abstract class AbstractDataSourceAdapter extends AbstractUnsupportedOperationDataSource implements AutoCloseable {
    
    private final DatabaseType databaseType;
    
    private final Map<String, DataSource> dataSourceMap;
    
    private ShardingTransactionManagerEngine shardingTransactionManagerEngine = new ShardingTransactionManagerEngine();
    
    private PrintWriter logWriter = new PrintWriter(System.out);
    
    public AbstractDataSourceAdapter(final Map<String, DataSource> dataSourceMap) throws SQLException {
        databaseType = getDatabaseType(dataSourceMap.values());
        shardingTransactionManagerEngine.init(databaseType, dataSourceMap);
        this.dataSourceMap = dataSourceMap;
    }
    
    protected final DatabaseType getDatabaseType(final Collection<DataSource> dataSources) throws SQLException {
        DatabaseType result = null;
        for (DataSource each : dataSources) {
            DatabaseType databaseType = getDatabaseType(each);
            Preconditions.checkState(null == result || result.equals(databaseType), String.format("Database type inconsistent with '%s' and '%s'", result, databaseType));
            result = databaseType;
        }
        return result;
    }
    
    private DatabaseType getDatabaseType(final DataSource dataSource) throws SQLException {
        if (dataSource instanceof AbstractDataSourceAdapter) {
            return ((AbstractDataSourceAdapter) dataSource).databaseType;
        }
        try (Connection connection = dataSource.getConnection()) {
            return DatabaseType.valueFrom(connection.getMetaData().getDatabaseProductName());
        }
    }
    
    @Override
    public final Logger getParentLogger() {
        return Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
    }
    
    @Override
    public final Connection getConnection(final String username, final String password) throws SQLException {
        return getConnection();
    }
    
    @Override
    public void close() throws Exception {
        for (DataSource each : dataSourceMap.values()) {
            try {
                Method method = each.getClass().getDeclaredMethod("close");
                method.setAccessible(true);
                method.invoke(each);
            } catch (final ReflectiveOperationException ignored) {
            }
        }
        shardingTransactionManagerEngine.close();
    }
}
  • AbstractDataSourceAdapter继承了AbstractUnsupportedOperationDataSource,实现了AutoCloseable接口;它的构造器接收一个DataSource的map,并执行shardingTransactionManagerEngine.init;close方法会遍历dataSourceMap,挨个反射调用执行close方法

ShardingTransactionManagerEngine

incubator-shardingsphere-4.0.0-RC1/sharding-transaction/sharding-transaction-core/src/main/java/org/apache/shardingsphere/transaction/ShardingTransactionManagerEngine.java

@Slf4j
public final class ShardingTransactionManagerEngine {
    
    private final Map<TransactionType, ShardingTransactionManager> transactionManagerMap = new HashMap<>();
    
    public ShardingTransactionManagerEngine() {
        loadShardingTransactionManager();
    }
    
    private void loadShardingTransactionManager() {
        for (ShardingTransactionManager each : ServiceLoader.load(ShardingTransactionManager.class)) {
            if (transactionManagerMap.containsKey(each.getTransactionType())) {
                log.warn("Find more than one {} transaction manager implementation class, use `{}` now",
                    each.getTransactionType(), transactionManagerMap.get(each.getTransactionType()).getClass().getName());
                continue;
            }
            transactionManagerMap.put(each.getTransactionType(), each);
        }
    }
    
    /**
     * Initialize sharding transaction managers.
     *
     * @param databaseType database type
     * @param dataSourceMap data source map
     */
    public void init(final DatabaseType databaseType, final Map<String, DataSource> dataSourceMap) {
        for (Entry<TransactionType, ShardingTransactionManager> entry : transactionManagerMap.entrySet()) {
            entry.getValue().init(databaseType, getResourceDataSources(dataSourceMap));
        }
    }
    
    private Collection<ResourceDataSource> getResourceDataSources(final Map<String, DataSource> dataSourceMap) {
        List<ResourceDataSource> result = new LinkedList<>();
        for (Map.Entry<String, DataSource> entry : dataSourceMap.entrySet()) {
            result.add(new ResourceDataSource(entry.getKey(), entry.getValue()));
        }
        return result;
    }
    
    /**
     * Get sharding transaction manager.
     *
     * @param transactionType transaction type
     * @return sharding transaction manager
     */
    public ShardingTransactionManager getTransactionManager(final TransactionType transactionType) {
        ShardingTransactionManager result = transactionManagerMap.get(transactionType);
        if (TransactionType.LOCAL != transactionType) {
            Preconditions.checkNotNull(result, "Cannot find transaction manager of [%s]", transactionType);
        }
        return result;
    }
    
    /**
     * Close sharding transaction managers.
     * 
     * @throws Exception exception
     */
    public void close() throws Exception {
        for (Entry<TransactionType, ShardingTransactionManager> entry : transactionManagerMap.entrySet()) {
            entry.getValue().close();
        }
    }
}
  • ShardingTransactionManagerEngine维护了ShardingTransactionManager的map,其构造器执行loadShardingTransactionManager方法,它会使用ServiceLoader.load(ShardingTransactionManager.class)加载,然后放入transactionManagerMap中;init方法会遍历transactionManagerMap,然后挨个执行init方法;close方法则遍历transactionManagerMap,挨个执行close方法

小结

AbstractDataSourceAdapter继承了AbstractUnsupportedOperationDataSource,实现了AutoCloseable接口;它的构造器接收一个DataSource的map,并执行shardingTransactionManagerEngine.init;close方法会遍历dataSourceMap,挨个反射调用执行close方法

doc

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊sharding-jdbc的AbstractDataSourceAdapter

    本文主要研究一下sharding-jdbc的AbstractDataSourceAdapter

    codecraft
  • 聊聊Elasticsearch的MonitorService

    elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/MonitorServic...

    codecraft
  • httpclient参数配置

    默认的话,是从response里头读timeout参数的,没有读到则设置为-1,这个代表无穷,这样设置是有点问题了,如果是https链接的话,则可能会经常报

    codecraft
  • 聊聊sharding-jdbc的AbstractDataSourceAdapter

    本文主要研究一下sharding-jdbc的AbstractDataSourceAdapter

    codecraft
  • java设计模式之构建模式,私人订制自己的创意

    创建对象的方法,通常的做法是通过构造方法,直接对属性赋值。或者先new一个对象,通过set方法对属性赋值,但是如果属性很多的情况下,构造方法需要注意属性赋值的顺...

    用户4361942
  • Android 框架学习4:一次读懂热门图片框架 Picasso 源码及流程

    就拿本篇文章要研究的图片加载框架来说,我们知道一个图片框架的核心功能就是:将图片显示到界面上。

    张拭心 shixinzhang
  • Lightning Open CTI: 为什么语音比以往更重要

    在数字领域,语音渠道仍然占据很重要的位置。语音的确非常重要,而且经常是客户体验中最重要的组成部分,目前来看企业的通话量并没有减少的趋势。选择销售和服务客户交互的...

    臭豆腐
  • 存储06-存储最佳实施规范

    连线方式一:扩柜子容易,直接加入和连线即可,简单;但是柜子01和02任意一个掉电后,存储的链路中断了

    大话IT架构
  • R语言入门之变量重编码与重命名

    在很多时候,我们需要对数据进行分类,比如根据血糖值将患者分成糖尿病组与非糖尿病组,亦或者按照年龄将样本分为老年人,中年人和青年人等等,这些就需要我们对数据进行重...

    生信与临床
  • ElasticSearch Aggregations GroupBy 实现源码分析

    也就是按newtype 字段进行group by,然后对num求平均值。在我们实际的业务系统中,这种统计需求也是最多的。

    用户2936994

扫码关注云+社区

领取腾讯云代金券