I am trying to write a batch application where needs I need to load the properties from database instead of properties files and keep then in memory until the process completes. What is the best way to implement it?
1 Answer
You can add custom properties to existing environment using ConfigurableEnvironment component.
Usually it make sense to do when application is fully initialized by listening for ContextRefreshedEventso in that moment it is possible to retrieve something from the database and merge with environment.
But you can bound it to your own lifecycle.
Here is a simple example.
Say this is your database property definition:
@Entity @Table(name = "database_properties") public static class DatabaseProperty extends AbstractPersistable<String> { private String name; private String value; public DatabaseProperty() {} public DatabaseProperty(String name, String value) { this.name = name; this.value = value; } public String getName() { return name; } public String getValue() { return value; } } With repository/dao:
interface DatabasePropertyRepository extends JpaRepository<So44850695Application.DatabaseProperty, String> {} This is how you can merge it with existing environment:
@Component public static class PropertyEnvironment implements ApplicationListener<ContextRefreshedEvent> { private final ConfigurableEnvironment configurableEnvironment; private final DatabasePropertyRepository propertiesRepository; @Autowired public PropertyEnvironment(ConfigurableEnvironment configurableEnvironment, DatabasePropertyRepository propertiesRepository) { this.configurableEnvironment = configurableEnvironment; this.propertiesRepository = propertiesRepository; } @Override public void onApplicationEvent(ContextRefreshedEvent event) { final Map<String, Object> properties = propertiesRepository.findAll().stream() .collect(Collectors.toMap(DatabaseProperty::getName, DatabaseProperty::getValue)); configurableEnvironment.getPropertySources().addLast(new MapPropertySource("db", properties)); } } I believe this is a simplest way.