Saltar al contenido

Cargar propiedades de la aplicación Spring Boot desde la base de datos

Solución:

Para aquellos que necesitan cargar propiedades de la base de datos antes de que se inicie la aplicación, y hacer que esos accesorios sean accesibles mediante @Value en cualquier lugar de su proyecto, simplemente agregue este procesador.

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<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.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

En application.properties deben existir datos de origen de datos para poder conectarse a la base de datos.

Luego en carpeta META-INF crear un archivo llamado fábricas de primavera y allí ponga la siguiente línea:

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

Y eso es todo, las propiedades retiradas serán accesibles en cualquier lugar.

Puede configurar los beans con los valores de la base de datos manualmente dependiendo de sus necesidades (de esta manera puede aprovechar Spring CDI y las configuraciones de la base de datos de arranque).

Tomemos como ejemplo la configuración del tiempo de espera de la sesión:

@SpringBootApplication
public class MySpringBootApplication extends SpringBootServletInitializer {           
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }

    @Bean
    public HttpSessionListener httpSessionListener(){
        return new MyHttpSessionListener();
    }
}

Luego, una definición de bean para configurar el bean:

import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

public class MyHttpSessionListener implements HttpSessionListener {   
    @Autowired
    private MyRepository myRepository;

    @Override
    public void sessionCreated(HttpSessionEvent se) {
        se.getSession().setMaxInactiveInterval(this.myRepository.getSessionTimeoutSeconds()); 
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        // Noop
    }

}

Nota: puede mover la llamada de la base de datos a una @PostConstruct método para evitar hacerlo para cada sesión.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *