Не всем, кто заинтересован в награде, но я возьму ее, если она все еще на столе. Это ОЧЕНЬ похоже на некоторый код, который я использую на $ DAYJOB, и поэтому это не теория, а то, что я использую в рабочем коде, но измененная для защиты виновных. Я не пробовал компилировать измененный код, поэтому предупреждаю, что я мог допустить некоторые ошибки при изменении имен и тому подобное, но все принципы, которые здесь приведены, были проверены и работают.
Во-первых, вам нужен квалификатор держателя стоимости. Используйте @Nonbinding, чтобы WELD не совпадал ТОЛЬКО с квалификаторами с одинаковыми значениями, поскольку мы хотим, чтобы все значения этого конкретного классификатора соответствовали одной точке внедрения. Сохраняя квалификатор и значение в одной и той же аннотации, вы не можете просто «забыть» одну из них случайно. (Поцелуй принцип)
@Qualifier
@Retention(RUNTIME)
@Target({METHOD, FIELD, PARAMETER, TYPE})
public @interface ConfigValue {
// Excludes this value from being considered for injection point matching
@Nonbinding
// Avoid specifying a default value, since it can encourage programmer error.
// We WANT a value every time.
String value();
}
Далее вам нужен метод продюсера, который знает, как получить карту. Вероятно, у вас должен быть Именованный бин, содержащий метод продюсера, так что вы можете явно инициализировать значение с помощью getter / setters, или же бин должен инициализировать его для вас.
Мы должны указать пустое значение для квалификатора в методе продюсера, чтобы избежать ошибок во время компиляции, но оно никогда не используется на практике.
@Named
public class ConfigProducer {
//@Inject // Initialize this parameter somehow
Map<String,String> configurationMap;
@PostConstructor
public void doInit() {
// TODO: Get the configuration map here if it needs explicit initialization
}
// In general, I would discourage using this method, since it can be difficult to control exactly the order in which beans initialize at runtime.
public void setConfigurationMap(Map<String,String> configurationMap) {
this.configurationMap = configurationMap;
}
@Produces
@ConfigValue("")
@Dependent
public String configValueProducer(InjectionPoint ip) {
// We know this annotation WILL be present as WELD won't call us otherwise, so no null checking is required.
ConfigValue configValue = ip.getAnnotated().getAnnotation(ConfigValue.class);
// This could potentially return a null, so the function is annotated @Dependent to avoid a WELD error.
return configurationMap.get(configValue.value());
}
}
Простое использование:
@Inject
@ConfigValue("some.map.key.here")
String someConfigValue;