Ответ 1
Я бы хотел, чтобы эта награда понравилась. Понимая это, я много рассказывал о внутренностях WELD, и здесь самый интересный урок: @Named является квалификатором и должен рассматриваться как таковой, если вы сможете сопоставить его.
У меня есть предупреждение для вас: если вам не хватает каких-либо значений в вашем приложении, это не удастся при развертывании или загрузке. Это может быть желательно для вас, но это специально означает, что значения по умолчанию невозможны.
Точка впрыска указана точно так же, как и у вас, и здесь код расширения, необходимый для его работы:
@ApplicationScoped
public class PerformSetup implements Extension {
Map<String, String> configMap;
public PerformSetup() {
configMap = new HashMap<String, String>();
// This is a dummy initialization, do something constructive here
configMap.put("string.value", "This is a test value");
}
// Add the ConfigMap values to the global bean scope
void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
// Loop through each entry registering the strings.
for (Entry<String, String> configEntry : configMap.entrySet()) {
final String configKey = configEntry.getKey();
final String configValue = configEntry.getValue();
AnnotatedType<String> at = bm.createAnnotatedType(String.class);
final InjectionTarget<String> it = bm.createInjectionTarget(at);
/**
* All of this is necessary so WELD knows where to find the string,
* what it named, and what scope (singleton) it is.
*/
Bean<String> si = new Bean<String>() {
public Set<Type> getTypes() {
Set<Type> types = new HashSet<Type>();
types.add(String.class);
types.add(Object.class);
return types;
}
public Set<Annotation> getQualifiers() {
Set<Annotation> qualifiers = new HashSet<Annotation>();
qualifiers.add(new NamedAnnotationImpl(configKey));
return qualifiers;
}
public Class<? extends Annotation> getScope() {
return Singleton.class;
}
public String getName() {
return configKey;
}
public Set<Class<? extends Annotation>> getStereotypes() {
return Collections.EMPTY_SET;
}
public Class<?> getBeanClass() {
return String.class;
}
public boolean isAlternative() {
return false;
}
public boolean isNullable() {
return false;
}
public Set<InjectionPoint> getInjectionPoints() {
return it.getInjectionPoints();
}
@Override
public String create(CreationalContext<String> ctx) {
return configValue;
}
@Override
public void destroy(String instance,
CreationalContext<String> ctx) {
// Strings can't be destroyed, so don't do anything
}
};
abd.addBean(si);
}
}
/**
* This is just so we can create a @Named annotation at runtime.
*/
class NamedAnnotationImpl extends AnnotationLiteral<Named> implements Named {
final String nameValue;
NamedAnnotationImpl(String nameValue) {
this.nameValue = nameValue;
}
public String value() {
return nameValue;
}
}
}
Я тестировал, что это сработало с помощью приложения WELD-SE:
@ApplicationScoped
public class App {
@Inject
@Parameters
List<String> parameters;
@Inject
@Named("string.value")
String stringValue;
public void printHello(@Observes ContainerInitialized event) {
System.out.println("String Value is " + stringValue);
}
}
Наконец, не забывайте /META -INF/services/javax.enterprise.inject.spi.Extension, заменив метод сварки с помощью используемого класса:
weldtest.PerformSetup
Это должно сделать всю эту работу. Дайте мне знать, если у вас возникнут какие-либо трудности, и я пришлю вам свой тестовый проект.