holysky5
10/17/2018 - 6:02 AM

SpringBoot DatabasePropertySource

使用数据库表当SpringBoot 属性源, 或者直接使用spring cloud config 从database中读取

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

public class ReadDBPropertiesInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    private static final Logger LOG = LoggerFactory.getLogger(ReadDBPropertiesInitializer.class);

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

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {

        ConfigurableEnvironment configEnv = ((ConfigurableEnvironment) applicationContext.getEnvironment());

        LOG.info("Load properties from database");

        Map<String, Object> propertySource = new HashMap<>();

        try {

            final String url = getEnv(configEnv, "spring.datasource.url");

            String driverClassName = getProperty(configEnv, "spring.datasource.driver-class-name");

            final String username = getEnv(configEnv, "spring.datasource.username");
            final String password = getEnv(configEnv, "spring.datasource.password");

            DataSource ds = DataSourceBuilder.create().url(url).username(username).password(password)
                    .driverClassName(driverClassName).build();

            // Fetch all properties
            PreparedStatement preparedStatement = ds.getConnection()
                    .prepareStatement("SELECT config_key as name, config_value as value, config_label as label FROM TB_CONFIGURATION");

            ResultSet rs = preparedStatement.executeQuery();

            // Populate all properties into the property source
            while (rs.next()) {             
                final String propName = rs.getString("name");
                final String propValue = rs.getString("value");
                final String propLabel = rs.getString("label");
                LOG.info(String.format("Property: %s | Label: %s", propName, propLabel));
                LOG.info(String.format("Value: %s", propValue));
                propertySource.put(propName, propValue);
            }

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

        } catch (Exception e) {
            throw new RuntimeException("Error fetching properties from db");
        }

    }

    private String getEnv(ConfigurableEnvironment configEnv, final String property) {
        MutablePropertySources propertySources = configEnv.getPropertySources();
        PropertySource<?> appConfigProp = propertySources.get("applicationConfigurationProperties");
        return System.getenv().get(((String) appConfigProp.getProperty(property)).replace("${", "").replace("}", ""));
    }

    private String getProperty(ConfigurableEnvironment configEnv, final String property) {
        MutablePropertySources propertySources = configEnv.getPropertySources();
        PropertySource<?> appConfigProp = propertySources.get("applicationConfigurationProperties");
        return (String) appConfigProp.getProperty(property);
    }
}