I just noticed that CDI makes it possible to write properties files in Java, instead of plain text. I'm not sure if this is useful, but it is cute.
We define our properties in a class. Of course, since the properties are going to be deployment-specific, we should declare the class @Alternative. (Unless it holds the default values, I suppose.)
@Alternative
class TestSettings {
@Produces @Named String adminUser = "admin";
@Produces @Named String adminPassword = "nimda";
@Produces @Named int maxRetries = 100;
}
Now, we can inject these properties. Into fields:
@Inject @Named int maxRetries;
Or even into constructors or methods:
@Inject
Connection(@Named("adminUser") String user,
@Named("adminPassword") String pass) {
...
}
To select the right settings class for a deployment, we list it in beans.xml:
<beans>
<alternatives>
<class>settings.TestSettings</class>
</alternatives>
</beans>
You could even write a really simple portable extension that would weave in the necessary @Alternative, @Produces and @Named annotations to the following class:
@Properties
class TestSettings {
String adminUser = "admin";
String adminPassword = "nimda";
int maxRetries = 100;
}
(If you want to know how to do this, go read up on the ProcessAnnotatedType event that is part of the CDI portable extension SPI.)
Well, I suppose it would be more typesafe to create a Settings interface with getter methods for all the properties, and inject that. Still, for an accidental
feature, this is kinda cool.
UPDATE: hrrrm ... this feature makes somewhat more sense, when you realize that TestSettings is also a perfect place to declare all your deployment specific resources.