读取application.yml
信息的类
// 该类读取的是 spring.shardingsphere.masterslave 下面的配置信息
@ConfigurationProperties(prefix = "spring.shardingsphere.masterslave")
public class SpringBootMasterSlaveRuleConfigurationProperties extends YamlMasterSlaveRuleConfiguration {
}
public class YamlMasterSlaveRuleConfiguration implements YamlConfiguration {
private String name;
private String masterDataSourceName;
private List<String> slaveDataSourceNames = new ArrayList();
private String loadBalanceAlgorithmType;
private Properties props = new Properties();
}
生成DataSource的过程
// shardingsphere\shardingjdbc\spring\boot\SpringBootConfiguration.class
@Configuration
@ComponentScan({"org.apache.shardingsphere.spring.boot.converter"})
@EnableConfigurationProperties({SpringBootShardingRuleConfigurationProperties.class,
SpringBootMasterSlaveRuleConfigurationProperties.class, SpringBootPropertiesConfigurationProperties.class})
@ConditionalOnProperty(
prefix = "spring.shardingsphere",
name = {"enabled"}, // 配置文件中 spring.shardingsphere.enabled 属性值不为false时, 加载这个Bean
havingValue = "true", // 和 name 搭配使用, name中的属性值和havingValue的值一样时, 加载这个Bean
matchIfMissing = true // 当name中的属性在配置文件中没有的时候, 也会加载这个Bean
)
@AutoConfigureBefore({DataSourceAutoConfiguration.class})
public class SpringBootConfiguration implements EnvironmentAware {
// 此时的这些属性已经装载了配置文件中的信息
private final SpringBootShardingRuleConfigurationProperties shardingRule;
private final SpringBootMasterSlaveRuleConfigurationProperties masterSlaveRule;
private final SpringBootPropertiesConfigurationProperties props;
private final Map<String, DataSource> dataSourceMap = new LinkedHashMap();
@Bean
// 是否加载要根据 matches 方法的返回值
@Conditional({MasterSlaveRuleCondition.class})
public DataSource masterSlaveDataSource(){
return MasterSlaveDataSourceFactory.createDataSource(this.dataSourceMap,
(new MasterSlaveRuleConfigurationYamlSwapper()).swap(this.masterSlaveRule), this.props.getProps());
}
}
public MasterSlaveRuleConfiguration swap(YamlMasterSlaveRuleConfiguration yamlConfiguration) {
return new MasterSlaveRuleConfiguration(yamlConfiguration.getName(), yamlConfiguration.getMasterDataSourceName(), yamlConfiguration.getSlaveDataSourceNames(), this.getLoadBalanceStrategyConfiguration(yamlConfiguration));
}
public MasterSlaveRuleConfiguration(String name, String masterDataSourceName, List<String> slaveDataSourceNames, LoadBalanceStrategyConfiguration loadBalanceStrategyConfiguration) {
// 可以看到 这里会检查 是否配置了这几个属性以及是否为空
Preconditions.checkArgument(!Strings.isNullOrEmpty(name), "Name is required.");
Preconditions.checkArgument(!Strings.isNullOrEmpty(masterDataSourceName), "MasterDataSourceName is required.");
Preconditions.checkArgument(null != slaveDataSourceNames && !slaveDataSourceNames.isEmpty(), "SlaveDataSourceNames is required.");
this.name = name;
this.masterDataSourceName = masterDataSourceName;
this.slaveDataSourceNames = slaveDataSourceNames;
this.loadBalanceStrategyConfiguration = loadBalanceStrategyConfiguration;
}
masterslave:
load-balance-algorithm-type: round_robin # 从库负载均衡策略
master-data-source-name: db1 # 主库
slave-data-source-names: db2 # 从库
name: ruiji # 如果不设置这个属性, 项目跑起来也运行不了, 而且不能设置为空字符
public final class MasterSlaveRuleCondition extends SpringBootCondition {
private static final String MASTER_SLAVE_NAME = "spring.shardingsphere.masterslave.name";
public ConditionOutcome getMatchOutcome(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
// 判断配置文件中是否有 这个属性, 没有这个属性, 就不会加载 masterSlaveDataSource
return conditionContext.getEnvironment().containsProperty("spring.shardingsphere.masterslave.name") ? ConditionOutcome.match() : ConditionOutcome.noMatch("Can't find ShardingSphere master-slave rule configuration in environment.");
}
}
public abstract class SpringBootCondition implements Condition {
// 根据 这个方法的返回值 判断是否需要加载
public final boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String classOrMethodName = getClassOrMethodName(metadata);
try {
ConditionOutcome outcome = this.getMatchOutcome(context, metadata);
this.logOutcome(classOrMethodName, outcome);
this.recordEvaluation(context, classOrMethodName, outcome);
return outcome.isMatch();
}
}
}