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