聊聊shardingjdbc的AbstractDataSourceAdapter

34次阅读

共计 5705 个字符,预计需要花费 15 分钟才能阅读完成。

本文主要研究一下 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

  • AbstractDataSourceAdapter

正文完
 0