暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SpringCloud Config使用JDBC配置

lebronchen 2018-09-15
759

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 EnvironmentRepositoryOrdered {

    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<StringString> next = (Map<StringString>) 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 KEYVALUE 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(11NOT NULL,
  `key` varchar(50DEFAULT NULL,
  `value` varchar(500DEFAULT NULL,
  `application` varchar(50DEFAULT NULL,
  `profile` varchar(50DEFAULT NULL,
  `lable` varchar(50DEFAULT 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只是其中一种配置的获取方式,如果自己感兴趣也可以自己重写一种获取方式,并且可以在查询上加一层缓存提高查询效率。


扫码关注,不迷路


文章转载自lebronchen,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论