Sharding-JDBC 使用 Nacos 作为配置中心 【上 源码分析】

Sharding-JDBC 使用 Nacos 作为配置中心

1.ShardJdbcDatasourceAutoinitConfig

@Configuration
public class ShardJdbcDatasourceAutoinitConfig {


    @Bean
    public ApplicationRunner runner(DataSource dataSource) {
        return args -> {
            System.out.println("dataSource.getConnection() = " + dataSource.getConnection());
        };
    }

}

这个类往Springboot中注入了ApplicationRunner Bean,Springboot在启动的时候就会调用这个runner

我们在使用 sdjdbc的时候,通常都会在配置中指定DataSource的驱动为 ShardingSphereDriver

spring:
  datasource:
    driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver

因此下一步就会通过 ShardingSphereDriver 去获取数据库连接

2. ShardingSphereDriver

首先会判断url是否 包含 dbc:shardingsphere: 如果有,就通过 DriverDataSourceCache 去获取数据源

    private final DriverDataSourceCache dataSourceCache = new DriverDataSourceCache();

    public ShardingSphereDriver() {
    }

    public Connection connect(String url, Properties info) throws SQLException {
        return this.acceptsURL(url) ? this.dataSourceCache.get(url).getConnection() : null;
    }
    
        public boolean acceptsURL(String url) {
        return null != url && url.startsWith("jdbc:shardingsphere:");
    }

3.DriverDataSourceCache

DriverDataSourceCache实例化时,dataSourceMap肯定是空的, this.dataSourceMap.containsKey(url) false,走

this.dataSourceMap.computeIfAbsent(url, DriverDataSourceCache::createDataSource) 方法,这个方法在调用前,会先执行 this.createDataSource() 方法

 private final Map<String, DataSource> dataSourceMap = new ConcurrentHashMap();

    public DriverDataSourceCache() {
    }

    public DataSource get(String url) {
        return this.dataSourceMap.containsKey(url) ? (DataSource)this.dataSourceMap.get(url) : (DataSource)this.dataSourceMap.computeIfAbsent(url, DriverDataSourceCache::createDataSource);
    }

    private static <T extends Throwable> DataSource createDataSource(String url) throws T {
        try {
            return YamlShardingSphereDataSourceFactory.createDataSource(ShardingSphereDriverURLManager.getContent(url));
        } catch (IOException var2) {
            throw new SQLException(var2);
        } catch (SQLException var3) {
            throw var3;
        }
    }

this.createDataSource

可以看到 通过 YamlShardingSphereDataSourceFactory.createDataSource 去创建数据源,而数据源的配置信息来源于 ShardingSphereDriverURLManager.getContent(url)

    private static <T extends Throwable> DataSource createDataSource(String url) throws T {
        try {
            return YamlShardingSphereDataSourceFactory.createDataSource(ShardingSphereDriverURLManager.getContent(url));
        } catch (IOException var2) {
            throw new SQLException(var2);
        } catch (SQLException var3) {
            throw var3;
        }
    }

4.ShardingSphereDriverURLManager

ShardingSphereDriverURLManager在获取配置信息时,会通过 ShardingSphereServiceLoader 去获取 ShardingSphereDriverURLProvider 的实现类并返回迭代器对象

 public static byte[] getContent(String url) {
        Iterator var1 = ShardingSphereServiceLoader.getServiceInstances(ShardingSphereDriverURLProvider.class).iterator();

        ShardingSphereDriverURLProvider each;
        do {
            if (!var1.hasNext()) {
                throw new DriverURLProviderNotFoundException(url);
            }

            each = (ShardingSphereDriverURLProvider)var1.next();
        } while(!each.accept(url));

        return each.getContent(url);
    }

5.ShardingSphereServiceLoader

调用的是静态方法,此时 静态成员 LOADERS 是空的,get返回null

  private static final Map<Class<?>, ShardingSphereServiceLoader<?>> LOADERS = new ConcurrentHashMap();

public static <T> Collection<T> getServiceInstances(Class<T> serviceInterface) {
      ShardingSphereServiceLoader<?> result = (ShardingSphereServiceLoader)LOADERS.get(serviceInterface);
    return null != result ? result.getServiceInstances() : ((ShardingSphereServiceLoader)LOADERS.computeIfAbsent(serviceInterface, ShardingSphereServiceLoader::new)).getServiceInstances();
}

那么就走 ((ShardingSphereServiceLoader)LOADERS.computeIfAbsent(serviceInterface, ShardingSphereServiceLoader::new)).getServiceInstances(); 方法

此方法先执行 OADERS.computeIfAbsent(serviceInterface, ShardingSphereServiceLoader::new)),参数serviceInterface是上一步传过来的 ShardingSphereDriverURLProvider ,然后再在调用ShardingSphereServiceLoader的有参构造方法

    private ShardingSphereServiceLoader(Class<T> serviceInterface) {
        this.serviceInterface = serviceInterface;
        this.validate();
        this.services = this.load();
    }

在构造方法中调用 this.load()

private Collection<T> load() {
    Collection<T> result = new LinkedList();
    Iterator var2 = ServiceLoader.load(this.serviceInterface).iterator();

    while(var2.hasNext()) {
        T each = var2.next();
        result.add(each);
    }

    return result;
}

ServiceLoader 是Java 平台提供的一种服务提供者查找机制 ,将实例化META-INF/services目录下的 ShardingSphereDriverURLProvider 实现类集合,拿到集合后,回到 ShardingSphereDriverURLManager 类中

6.ShardingSphereDriverURLManager.getContent

Iterator var1 = ShardingSphereServiceLoader.getServiceInstances(ShardingSphereDriverURLProvider.class).iterator();

ShardingSphereDriverURLProvider each;
do {
    if (!var1.hasNext()) {
        throw new DriverURLProviderNotFoundException(url);
    }

    each = (ShardingSphereDriverURLProvider)var1.next();
} while(!each.accept(url));

      return each.getContent(url);

通过do{}while 遍历 ShardingSphereDriverURLProvider 集合,调用 accept()方法,如果返回true,将跳出循环,接着调用 each.getContent(url) 获取数据源配置信息

看到这,我想你应该知道怎么去使用nacos作为数据源的配置中心里,代码放到下一篇,感谢观看

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

秋日的晚霞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值