我现在想要这个赏金。弄清楚这一点教会了我很多关于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's 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:
weldtest.PerformSetup
这应该使所有这些工作。如果您遇到任何困难,请告诉我,我会将我的测试项目发送给您。