序
本文主要研究一下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村刨,聲明實現(xiàn)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,實現(xiàn)了AutoCloseable接口;它的構(gòu)造器接收一個DataSource的map,并執(zhí)行shardingTransactionManagerEngine.init氧秘;close方法會遍歷dataSourceMap,挨個反射調(diào)用執(zhí)行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趴久,其構(gòu)造器執(zhí)行l(wèi)oadShardingTransactionManager方法丸相,它會使用ServiceLoader.load(ShardingTransactionManager.class)加載,然后放入transactionManagerMap中彼棍;init方法會遍歷transactionManagerMap灭忠,然后挨個執(zhí)行init方法;close方法則遍歷transactionManagerMap座硕,挨個執(zhí)行close方法
小結(jié)
AbstractDataSourceAdapter繼承了AbstractUnsupportedOperationDataSource弛作,實現(xiàn)了AutoCloseable接口;它的構(gòu)造器接收一個DataSource的map华匾,并執(zhí)行shardingTransactionManagerEngine.init映琳;close方法會遍歷dataSourceMap,挨個反射調(diào)用執(zhí)行close方法