1.SpringCloud Config原理
SpringCloud Config支持多种数据配置,包括git、svn、vault、jdbc和本地文件存储,多种配置方式适合我们在不同的场景下去使用。
考虑到配置的安全性以及可管理性,jdbc方式便于我们管理配置,所以今天来介绍一下使用jdbc配置的方式。
Spring Cloud的核心包是spring-cloud-config-server.jar,这个jar的注入类是EnvironmentRepositoryConfiguration,我们来看一下这个类的源码:
```
@Configuration
@Import({ JdbcRepositoryConfiguration.class,
VaultRepositoryConfiguration.class,
SvnRepositoryConfiguration.class,
NativeRepositoryConfiguration.class,
GitRepositoryConfiguration.class,
DefaultRepositoryConfiguration.class })
public class EnvironmentRepositoryConfiguration {
...
}
通过源码我们可以看到config支持jdbc、value、svn、git和本地文件等多种配置方式。
今天我们要介绍的是jdbc的配置方式,所以我们再打开JdbcRepositoryConfiguration源码:
@Configuration
@Profile("jdbc")
class JdbcRepositoryConfiguration {
@Bean
public JdbcEnvironmentRepository jdbcEnvironmentRepository(JdbcTemplate jdbc) {
return new JdbcEnvironmentRepository(jdbc);
}
}
通过@Profile("jdbc")这个注解我们知道可以使用spring.profiles.active配置来激活jdbc配置config,我们可以在application.properties中能够添加配置:
spring.profiles.active=jdbc
这样就能够将jdbc作为config的默认读取方式。
下面再来跟进JdbcEnvironmentRepository源码看一下:
@ConfigurationProperties("spring.cloud.config.server.jdbc")
public class JdbcEnvironmentRepository implements EnvironmentRepository, Ordered {
private static final String DEFAULT_SQL = "SELECT KEY, VALUE from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?";
private int order = Ordered.LOWEST_PRECEDENCE - 10;
private final JdbcTemplate jdbc;
private String sql = DEFAULT_SQL;
private final PropertiesResultSetExtractor extractor = new PropertiesResultSetExtractor();
public JdbcEnvironmentRepository(JdbcTemplate jdbc) {
this.jdbc = jdbc;
}
@Override
public Environment findOne(String application, String profile, String label) {
String config = application;
if (StringUtils.isEmpty(label)) {
label = "master";
}
if (StringUtils.isEmpty(profile)) {
profile = "default";
}
if (!profile.startsWith("default")) {
profile = "default," + profile;
}
String[] profiles = StringUtils.commaDelimitedListToStringArray(profile);
Environment environment = new Environment(application, profiles, label, null,
null);
if (!config.startsWith("application")) {
config = "application," + config;
}
List<String> applications = new ArrayList<String>(new LinkedHashSet<>(
Arrays.asList(StringUtils.commaDelimitedListToStringArray(config))));
List<String> envs = new ArrayList<String>(new LinkedHashSet<>(Arrays.asList(profiles)));
Collections.reverse(applications);
Collections.reverse(envs);
for (String app : applications) {
for (String env : envs) {
Map<String, String> next = (Map<String, String>) jdbc.query(this.sql,
new Object[] { app, env, label }, this.extractor);
if (!next.isEmpty()) {
environment.add(new PropertySource(app + "-" + env, next));
}
}
}
return environment;
}
}
可以发现JdbcEnvironmentRepository类构造方法的参数是JdbcTemplate,所以JdbcEnvironmentRepository是使用JdbcTemplate来实现对数据库中配置的查询。
同时也提供了默认的查询sql:
SELECT KEY, VALUE from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?
并且JdbcEnvironmentRepository类中还提供了查询语句,findOne方法根据JdbcEnvironmentRepository类application, profile, label三个属性来数据库中查询key-value键值对。
2.SpringCloud Config JDBC配置使用
基于约定由于配置的原则,我们实现jdbc配置的过程就根据JdbcEnvironmentRepository类的规则来。
建表
这里我们使用mysql,首先创建表properties:
CREATE TABLE `properties` (
`id` int(11) NOT NULL,
`key` varchar(50) DEFAULT NULL,
`value` varchar(500) DEFAULT NULL,
`application` varchar(50) DEFAULT NULL,
`profile` varchar(50) DEFAULT NULL,
`lable` varchar(50) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
添加依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
配置applicatioon.properties
server.port=1700
spring.application.name=cloud-config-jdbc-server
#数据库配置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/config?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=xxx
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.cloud.config.label=master
spring.cloud.config.server.jdbc=true
spring.cloud.config.server.jdbc.sql=SELECT `KEY`, `VALUE` from PROPERTIES where APPLICATION=? and PROFILE=? and LABEL=?
spring.profiles.active=jdbc
启动类加上@EnableConfigServer注解
在数据库添加配置
INSERT INTO `properties` VALUES (null, 'foo', 'my config value', 'my application', 'dev', 'master');
这样我们的的配置就结束了。
SpringCloud Config配置的原理就是根据不同的方式去获取到存储好的配置设置到Environment对象中返回给服务方。JDBC只是其中一种配置的获取方式,如果自己感兴趣也可以自己重写一种获取方式,并且可以在查询上加一层缓存提高查询效率。
扫码关注,不迷路





