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作为数据源的配置中心里,代码放到下一篇,感谢观看