Load spring boot app properties from database

后端 未结 3 2069
傲寒
傲寒 2020-12-24 15:17

I need you to advice me with this issue, in a spring boot application I load some properties from database like (cron periods, email data), I need to export these properties

3条回答
  •  一个人的身影
    2020-12-24 15:59

    For those who need load properties from database before application starts, and make those props accesible by @Value anywhere in your project, just add this processor.

    public class ReadDbPropertiesPostProcessor implements EnvironmentPostProcessor {
    /**
     * Name of the custom property source added by this post processor class
     */
    private static final String PROPERTY_SOURCE_NAME = "databaseProperties";
    
    private String[] KEYS = {
            "excel.threads",
            "cronDelay",
            "cronDelayEmail",
            "spring.mail.username",
            "spring.mail.password",
            "spring.mail.host",
            "spring.mail.port",
            "spring.mail.properties.mail.transport.protocol",
            "spring.mail.properties.mail.smtp.auth",
            "spring.mail.properties.mail.smtp.starttls.enabled",
            "spring.mail.properties.mail.debug",
            "spring.mail.properties.mail.smtp.starttls.required",
            "spring.mail.properties.mail.socketFactory.port",
            "spring.mail.properties.mail.socketFactory.class",
            "spring.mail.properties.mail.socketFactory.fallback",
            "white.executor.threads",
            "white.search.threads",
            "lot.sync.threads",
            "lot.async.threads",
            "lot.soap.threads",
            "excel.async.threads",
            "kpi.threads",
            "upload.threads"
    };
    
    /**
     * 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 propertySource = new HashMap<>();
    
        try {
    
            // Build manually datasource to ServiceConfig
            DataSource ds = DataSourceBuilder
                    .create()
                    .username(environment.getProperty("spring.datasource.username"))
                    .password(environment.getProperty("spring.mail.password"))
                    .url(environment.getProperty("spring.datasource.url"))
                    .driverClassName("com.mysql.jdbc.Driver")
                    .build();
    
            // Fetch all properties
    
            Connection connection = ds.getConnection();
    
            JTrace.genLog(LogSeverity.informational, "cargando configuracion de la base de datos");
    
            PreparedStatement preparedStatement = connection.prepareStatement("SELECT value FROM config WHERE id = ?");
    
            for (int i = 0; i < KEYS.length; i++) {
    
                String key = KEYS[i];
    
                preparedStatement.setString(1, key);
    
                ResultSet rs = preparedStatement.executeQuery();
    
                // Populate all properties into the property source
                while (rs.next()) {
                    propertySource.put(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);
        }
    }
    } // class ReadDbPropertiesPostProcessor end
    

    In application.properties must exist datasource data in order to be able to connect to database.

    Then in folder META-INF create a file named spring.factories an there put the following line:

    org.springframework.boot.env.EnvironmentPostProcessor=test.config.ReadDbPropertiesPostProcessor
    

    And that's it, retreived properties will be accessible anywhere.

提交回复
热议问题