Springboot 以数据库为配置源

179 阅读1分钟

注入一个表作为配置源的PropertySource。PostProcessor实现了EnvironmentPostProcessor接口,每当Springboot程序重启时都会被执行

public class DbPropertiesPostProcessor implements EnvironmentPostProcessor {

    /**
     * Name of the custom property source added by this post processor class
     */
    private static final String PROPERTY_SOURCE_NAME = "databaseProperties";

    /**
     * Adds Spring Environment custom logic. This custom logic fetch properties from database and setting highest precedence
     */
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        Map<String, Object> propertySource = new HashMap<>();

        try {
            // Build manually datasource to ServiceConfig
            DataSource ds = DataSourceBuilder
                    .create()
                    .username(environment.getProperty("spring.datasource.username"))
                    .password(environment.getProperty("spring.datasource.password"))
                    .url(environment.getProperty("spring.datasource.jdbc-url"))
                    .driverClassName("com.mysql.jdbc.Driver")
                    .build();

            // Fetch all properties
            Connection connection = ds.getConnection();

            log.info("cargando configuracion de la base de datos");

            PreparedStatement preparedStatement = connection.prepareStatement("select `key` , `value` from  sys_config where `status` = 1");

            ResultSet rs = preparedStatement.executeQuery();

            // Populate all properties into the property source
            while (rs.next()) {
                propertySource.put(rs.getString("key"), rs.getString("value"));
            }

            rs.close();
            preparedStatement.clearParameters();
            preparedStatement.close();
            connection.close();

            // Create a custom property source with the highest precedence and add it to Spring Environment
            environment.getPropertySources().addFirst(new MapPropertySource(PROPERTY_SOURCE_NAME, propertySource));

        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
    }
}

resource/META-INF目录下新建spring.factories文件。类型Springboot Starter 通过spring.factories 文件制定的类会被Spring加载到容器中。

org.springframework.boot.env.EnvironmentPostProcessor=github.jiancai.wang.web.core.DbPropertiesPostProcessor

通过SpringCloud的ContextRefresher完成配置热更新