ShardingSphere問題解決(一)

概要:錯誤信息 Data sources cannot be empty

  • shardingSphere版本
    shardingshpere_version=4.1.0
    sharding_jdbc_spring_namespace_version=4.1.0
compile("org.apache.shardingsphere:sharding-jdbc-spring-boot-starter:${shardingshpere_version}")
compile("org.apache.shardingsphere:sharding-jdbc-spring-namespace:${sharding_jdbc_spring_namespace_version}")
  • 詳細異常明細
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.sql.DataSource]: Factory method 'shardingDataSource' threw exception; nested exception is java.lang.IllegalArgumentException: Data sources cannot be empty.
 at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
 at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:582)
 ... 104 common frames omitted
Caused by: java.lang.IllegalArgumentException: Data sources cannot be empty.
 at com.google.common.base.Preconditions.checkArgument(Preconditions.java:134)
 at org.apache.shardingsphere.core.rule.ShardingRule.<init>(ShardingRule.java:76)
 at org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory.createDataSource(ShardingDataSourceFactory.java:48)
 at org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration.shardingDataSource(SpringBootConfiguration.java:103)
 at org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration$$EnhancerBySpringCGLIB$$a2810b5d.CGLIB$shardingDataSource$1(<generated>)
 at org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration$$EnhancerBySpringCGLIB$$a2810b5d$$FastClassBySpringCGLIB$$b2e37f70.invoke(<generated>)
 at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
 at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:361)
 at org.apache.shardingsphere.shardingjdbc.spring.boot.SpringBootConfiguration$$EnhancerBySpringCGLIB$$a2810b5d.shardingDataSource(<generated>)
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
 at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
 at java.lang.reflect.Method.invoke(Method.java:497)
 at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
 ... 105 common frames omitted

  • 查看源碼
    ShardingRule.class,發現 dataSourceNames 節點爲空
public ShardingRule(final ShardingRuleConfiguration shardingRuleConfig, final Collection<String> dataSourceNames) {
    Preconditions.checkArgument(null != shardingRuleConfig, "ShardingRuleConfig cannot be null.");

	Preconditions.checkArgument(null != dataSourceNames && !dataSourceNames.isEmpty(), "Data sources cannot be empty.");
	    this.ruleConfiguration = shardingRuleConfig;
	
	shardingDataSourceNames = new ShardingDataSourceNames(shardingRuleConfig, dataSourceNames);
	
	tableRules = createTableRules(shardingRuleConfig);
	
	broadcastTables = shardingRuleConfig.getBroadcastTables();
	
	bindingTableRules = createBindingTableRules(shardingRuleConfig.getBindingTableGroups());
	
	defaultDatabaseShardingStrategy = createDefaultShardingStrategy(shardingRuleConfig.getDefaultDatabaseShardingStrategyConfig());
	
	defaultTableShardingStrategy = createDefaultShardingStrategy(shardingRuleConfig.getDefaultTableShardingStrategyConfig());
	
	defaultShardingKeyGenerator = createDefaultKeyGenerator(shardingRuleConfig.getDefaultKeyGeneratorConfig());
	
	masterSlaveRules = createMasterSlaveRules(shardingRuleConfig.getMasterSlaveRuleConfigs());
	
	encryptRule = createEncryptRule(shardingRuleConfig.getEncryptRuleConfig());
}

反調至SpringBootConfiguration.class,發現數據源信息取自dataSourceMap

@Bean
@Conditional(ShardingRuleCondition.class)
public DataSource shardingDataSource() throws SQLException {

	return ShardingDataSourceFactory.createDataSource(dataSourceMap, new ShardingRuleConfigurationYamlSwapper().swap(shardingRule), props.getProps());
}

dataSourceMap賦值邏輯爲

@Override
public final void setEnvironment(final Environment environment) {
    String prefix = "spring.shardingsphere.datasource.";
    for (String each : getDataSourceNames(environment, prefix)) {

		try {
		
			dataSourceMap.put(each, getDataSource(environment, prefix, each));
		
		} catch (final ReflectiveOperationException ex) {
		
			throw new ShardingSphereException("Can't find datasource type!", ex);
		
		} catch (final NamingException namingEx) {
		
			throw new ShardingSphereException("Can't find JNDI datasource!", namingEx);
		
		}
	}
}

從而可知數據源yaml配置文件因該爲:spring.shardingsphere.datasource.
而自己的項目配置爲sharding.dataSource

加載配置文件時沒有問題,可以注入數據源和路由規則,當 @Conditional(ShardingRuleCondition.class) 生效時,會在環境中重新加載默認路徑數據源,導致啓動失敗。

  • 解決方案
    配置默認數據源路徑即可
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章