Hi Chris,
thanks for your examples! Injecting an Environment, I can indeed work without a PropertySourcesPlaceholderConfigurer like this:
Code:
@Configuration
@PropertySource("file:${MY_CONFIG}")
public class TcmDataSourceSpringConfig {
@Inject
private Environment env;
@Bean
public DataSource myDataSource() {
String host = env.getProperty("myapp.jdbc.host");
String database = env.getProperty("myapp.jdbc.database");
String username = env.getProperty("myapp.jdbc.username");
String password = env.getProperty("myapp.jdbc.password");
String url = String.format("jdbc:mysql://%s/%s", host, database);
DriverManagerDataSource ds = new DriverManagerDataSource(url);
ds.setUsername(username);
ds.setPassword(password);
return ds;
}
}
It's good to know that the @PropertySource annotation is able to interpolate a system environment variable - I was afraid this might not work but it does :-)
Now I'm just wondering if it's possible to combine this new style @PropertySource configuration with old-style @Value injection?
Code:
@Value("${myapp.jdbc.host"}
private String host;
is a bit more concise than using env.getProperty(...) all over the place, and putting all the @Value-annotated members at the top of your configuration class, you can easily see all the external properties that your configuration depends on.
I've tried this, but the ${...} expression does not get interpolated.
On a side note, I'm not sure if it's common practice to reference a properties file by an environment variable, and maybe this can also be simplified with some of the new Spring 3.1 features. The reasons for taking this approach are:
- Our properties contain host specific settings. So we can't reference them from the classpath (which would amount to packaging the properties file into the JAR or WAR).
- We can't use a @PropertySource("file:/path/to/myapp.properties") because file system structures vary from host to host.
- We can't use a @PropertySource("file:${my.config}")) where my.config is a Java system property because this does not work well when running JUnit tests interactively from Eclipse - you'd have to manually add this system property to the launcher for every single test.
Indirectly referencing a properties file via a system environment variable is the only way we've found so far to cover all development and production scenarios, working with or without Maven and with or without Eclipse.
Maybe not elegant, but it works... Any ideas for improvement are welcome!
Best regards,
Harald