I am loading my properties file as following:
@Configuration
@PropertySource("classpath:app.properties")
class MyApp {
@Bean
public PropertySourcesPlaceholderConfigurer PropertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
In the properties file, I have several database-related properties:
database.dataSource.url=jdbc:postgresql://localhost:${db-port:5432}/mydb
database.dataSource.x=...
database.dataSource.y=...
database.dataSource.z=...
Note:
${db-port}
should be replaced by either the value of property/environment variabledb-port
or 5432. In my case, I am defining the environment variabledb-port
when spawning the Tomcat container.All database-related properties are grouped under
database.
root. This is intentional, see below.
I want to avoid that I have to enumerate/hardcode all possible database-related properties in my code. Luckily, the database layer in use (Hikari) has the nice feature that I can pass all properties via a java.util.Properties
. So, I want retrieve all defined properties under database.*
and simply forward it to Hikari.
For this, I wrote the following utility:
@Component
public class PropertyFetcher
{
@Autowired
private ConfigurableEnvironment environment;
public Properties get(final String key) {
final Properties p = new Properties();
for (final PropertySource<?> s : environment.getPropertySources()) {
if (s instanceof EnumerablePropertySource) {
for (final String k : ((EnumerablePropertySource) s).getPropertyNames()) {
if (k.startsWith(key) && k.length() > key.length()) {
p.put(k.substring(key.length()), s.getProperty(k));
}
}
}
}
return p;
}
}
Now, when calling get("database.")
, I have all database-related properties as defined in the properties file. Great! But, the value for property dataSource.url
is now
jdbc:postgresql://localhost:${db-port:5432}/mydb
instead of
jdbc:postgresql://localhost:9876/mydb
So, for some reason, the ${db-port:5432}
is not resolved (yet?) when going via this route (ConfigurableEnvironment
).
How can this be fixed? Or is there a better way to get all properties under a certain root without having to enumerate/hardcode them into the code?
Please note that in the default scenario, the ${db-port:5432}
in property database.dataSource.url=jdbc:postgresql://localhost:${db-port:5432}/mydb
is correctly resolved. I tested this by defining the following member and logging it:
@Value("${database.dataSource.url}")
final String url; // holds jdbc:postgresql://localhost:9876/mydb