读前请注意
本文涉及的源码修改并没有经过严格的验证或大量测试,谨慎参考.
另修改部分可在(github.com/jiangxiewei/jxw-sharding-jdbc)上查阅
RELEASE-1.0.0(我们生产跑老久了😂)
基于sharding-jdbc 3.1.0版本进行修改.(非apache版本)
提前了ConfigMapContext的初始化操作,使用户的sharding-algorithm在使用时能正常拿到配置值.
修复了sharding-jdbc一个异常无法抛出的bug(只能抛出NullPointerException,隐藏了真实异常).
给基于hint(暗示)的路由方式中,setShardingValue进行的强制数据库路由添加了SQL解析模块(之前是跳过的).并给HintShardingAlgorithm添加了解析出来的表名. PS:此修改仅对基于hint的强制路由和 prepareStatement形式的查询进行过简单测试,其他情况使用请慎重.
原版不支持包含UNION的SQL解析,此处特意放开这个限制,可能会引入BUG,可自行修改关闭.
提前configMapContext的注入便于shardingAlgorithm使用
总的来说
ShardingDataSource初始化时会读取"sharding.jdbc.config.config-map"配置放入configMapContext类中.
但是用户自定义的shardingAlgorithm初始化先于configMapContext. 所以我给他提前了.
具体来说
下面这是读取配置的部分
@ConfigurationProperties(prefix = "sharding.jdbc.config")
public class SpringBootConfigMapConfigurationProperties {
private Map configMap = new LinkedHashMap<>();
}
下面是修改部分.
@EnableConfigurationProperties({
SpringBootShardingRuleConfigurationProperties.class, SpringBootMasterSlaveRuleConfigurationProperties.class,
SpringBootConfigMapConfigurationProperties.class, SpringBootPropertiesConfigurationProperties.class
})
public class SpringBootConfiguration implements EnvironmentAware {
//此处为spring读取的sharding.jdbc.config配置.
private final SpringBootConfigMapConfigurationProperties configMapProperties;
@Bean
public DataSource dataSource() throws SQLException {
// ------------------以下为手动添加的部分------------------
if (!configMapProperties.getConfigMap().isEmpty()) {
ConfigMapContext.getInstance().getConfigMap().putAll(configMapProperties.getConfigMap());
}
// ------------------以上为手动添加的部分------------------
//shardingProperties.getShardingRuleConfiguration()会对ShardingAlgorithm进行实例化,此时configMapContetx尚未初始化.
return null == masterSlaveProperties.getMasterDataSourceName()
? ShardingDataSourceFactory
.createDataSource(dataSourceMap, shardingProperties.getShardingRuleConfiguration(), configMapProperties.getConfigMap(), propMapProperties.getProps())
: MasterSlaveDataSourceFactory.createDataSource(
dataSourceMap, masterSlaveProperties.getMasterSlaveRuleConfiguration(), configMapProperties.getConfigMap(), propMapProperties.getProps());
}
}
/**
*下面是ShardingDataSource的构造函数
*/
public class ShardingDataSource extends AbstractDataSourceAdapter {
public ShardingDataSource(final Map dataSourceMap, final ShardingRule shardingRule, final Map configMap, final Properties props) throws SQLException {
super(dataSourceMap);
checkDataSourceType(dataSourceMap);
//原来是在此处进行configMapContext的初始化.
if (!configMap.isEmpty()) {
ConfigMapContext.getInstance().getConfigMap().putAll(configMap);
}
shardingContext = new ShardingContext(getDataSourceMap(), shardingRule, getDatabaseType(), props);
}
}
解释:
原本ConfigMapContext读取"sharding.jdbc.config"的配置是在ShradingDatasource初始化的时候注入的.但是ShardingDatasource初始化的时候先进行了ShardingRule的初始化(此时进行了ShardingAlgorithm的实例化),故在ShardingAlgorithm中初始化获取ConfigMapContext的时候还没有获取到配置文件中的配置.
莫名的NullPointerException
总的来说
执行报错,抛空指针异常,发现真实异常被finally代码块中的异常覆盖了.然后改代码放出异常以便排查真正的报错原因.
具体