Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot: Use database and application.properties for configuration

I need to save the configuration of the Spring Boot application in the database.

Is it possible to store the database information in the application.properties and use them to connect to the database and retrieve all the other properties from there?

So my application.properties would look like:

spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=mydb
spring.datasource.username=user
spring.datasource.password=123456
spring.jpa.database-platform=org.hibernate.dialect.SQLServer2012Dialect

And the other configuration would be fetched from the database with something like this:

@Configuration
@PropertySource(value = {"classpath:application.properties"})
public class ConfigurationPropertySource {

    private final ConfigurationRepository configurationRepository;

    @Autowired
    public ConfigurationPropertySource(ConfigurationRepository configurationRepository) {
        this.configurationRepository = configurationRepository;
    }

    public String getValue(String key) {
        ApplicationConfiguration configuration = configurationRepository.findOne(key);
        return configuration.getValue();
    }

}

With ApplicationConfiguration as an Entity.

But Spring Boot does not get the configuration from the database.

like image 367
deve Avatar asked Nov 07 '16 12:11

deve


People also ask

Where do you put database properties in spring boot application?

To access the Relational Database by using JdbcTemplate in Spring Boot application, we need to add the Spring Boot Starter JDBC dependency in our build configuration file. Then, if you @Autowired the JdbcTemplate class, Spring Boot automatically connects the Database and sets the Datasource for the JdbcTemplate object.

Can we use both application properties and application Yml in spring boot?

Overview. A common practice in Spring Boot is using an external configuration to define our properties. This allows us to use the same application code in different environments. We can use properties files, YAML files, environment variables and command-line arguments.

What are the application properties in Spring Boot?

Inside the application properties file, we define every type of property like changing the port, database connectivity, connection to the eureka server, and many more. Now let’s see some examples for better understanding. Sometimes when you run your spring application you may encounter the following type of error

How to configure MySQL for Spring Boot application?

Configuring MySQL for Spring Boot Application. 1 1. MySQL Database Configuration. I will not cover installing MySQL server on your machine or how to create a new database in the MySQL. For this post, ... 2 2. Adding MySQL Dependencies. 3 3. Configure MySQL Using Spring Boot Properties. 4 4. Create JPA Entity. 5 5. Create User Repository. More items

Why do we use @configuration in Spring Boot?

We use @Configuration so that Spring creates a Spring bean in the application context. @ConfigurationProperties works best with hierarchical properties that all have the same prefix; therefore, we add a prefix of mail. The Spring framework uses standard Java bean setters, so we must declare setters for each of the properties.

How to configure an environment variable in Spring Boot?

You can use a different file as property file –spring.config.location=classpath:/default.properties You can configure an environment variable @Value is the basic approach for application configuration using Spring. Application Configuration using Type-safe Configuration Properties


2 Answers

I know that this an old question, but this post surely help someone like me who is struggling to find an exact solution.

We always love to write configurable code.

What if properties in database are available through @Value annotation ? Yes it is possible.

You just have to define a class which implements EnvironmentAware and add custom logic in setEnvironment method.


Let's start coding.

Define a database entity.

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "app_config")
public class AppConfig {
    @Id
    private String configKey;

    private String configValue;
}

Define a JPA repository to fetch configurations from database.

@Repository
public interface AppConfigRepo extends JpaRepository<AppConfig, String> {
}

Below code will load database properties into application environment.

@Component("applicationConfigurations")
public class ApplicationConfigurations implements EnvironmentAware {

    @Autowired
    private AppConfigRepo appConfigRepo;

    @Override
    public void setEnvironment(Environment environment) {
        ConfigurableEnvironment configurableEnvironment = (ConfigurableEnvironment) environment;

        Map<String, Object> propertySource = new HashMap<>();
        appConfigRepo.findAll().stream().forEach(config -> propertySource.put(config.getConfigKey(), config.getConfigValue()));
        configurableEnvironment.getPropertySources().addAfter("systemEnvironment", new MapPropertySource("app-config", propertySource));
    }
}

We can add our database properties one level below system environment so that we can easily override without touching the database. Below code line helps us to achieve the same.

configurableEnvironment.getPropertySources().addAfter("systemEnvironment", new MapPropertySource("app-config", propertySource));

You have to add @DependsOn annotation on class where you want to use @Value annotation.

@DependsOn takes application configuration bean id as parameter so that our properties from database are loaded in environment before our custom beans load.

So, class will look like this

@Component
@DependsOn("applicationConfigurations")
public class SomeClass {

    @Value("${property.from.database}")
    private String property;

    // rest of the code
}

Please note, JPA configurations are added in application.properties.

like image 145
Nikhil Pate Avatar answered Sep 29 '22 12:09

Nikhil Pate


One possible solution that you could workout, is to use ConfigurableEnvironment and reload and add properties.

@Configuration   
public class ConfigurationPropertySource {

private ConfigurableEnvironment env;

private final ConfigurationRepository configurationRepository;

    @Autowired
    public ConfigurationPropertySource(ConfigurationRepository configurationRepository) {
        this.configurationRepository = configurationRepository;
    }

    @Autowired
    public void setConfigurableEnvironment(ConfigurableEnvironment env) {

        this.env = env;
   }

   @PostConstruct
   public void init() {
    MutablePropertySources propertySources = env.getPropertySources();
       Map myMap = new HashMap();
       //from configurationRepository get values and fill mapp
       propertySources.addFirst(new MapPropertySource("MY_MAP", myMap));
   }

}
like image 22
kuhajeyan Avatar answered Sep 29 '22 12:09

kuhajeyan