How To Configure Java EE 6+ Applications ...Without XML 📎
@Inject
:
@Singleton
@Startup
public class HitsFlushTimer {
@Inject
private int hitsFlushRate;
}
The injected values are returned by a method with matching return type and denoted with the @Produces annotation. Usually a dedicated component (EJB 3.1, CDI managed bean, or usual Java class) manages the configuration:
@Startup
@Singleton
public class Configuration {
private Map configuration;
private Set unconfiguredFields;
@Inject
private Instance configurationProvider;
@PostConstruct
public void fetchConfiguration() {
//default values...
this.configuration = new HashMap() {{
put("hitsFlushRate", "1");
//...
}};
this.unconfiguredFields = new HashSet();
mergeWithCustomConfiguration();
}
@javax.enterprise.inject.Produces
public String getString(InjectionPoint point) {
String fieldName = point.getMember().getName();
String valueForFieldName = configuration.get(fieldName);
if (valueForFieldName == null) {
this.unconfiguredFields.add(fieldName);
}
return valueForFieldName;
}
@javax.enterprise.inject.Produces
public int getInteger(InjectionPoint point) {
String stringValue = getString(point);
if (stringValue == null) {
return 0;
}
return Integer.parseInt(stringValue);
}
//...
}
The most interesting feature is the
InjectionPoint
argument in the method: public String getString(InjectionPoint point)
. It represents the injection point :-) and gives you information about the field, it's name and class. The InjectionPoint can be used to uniquely identify and so configure each field of a class individually.
[x-ray's cache flushing was configured that way. You will also find the code above in the git repo, See also page 98 "Configuration Over Convention with Inversion of Control" in Real World Java EE Night Hacks--Dissecting the Business Tier.]