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