【发布时间】:2014-09-08 00:41:46
【问题描述】:
如何以编程方式将 Java CDI 1.1+ 托管 bean 注入静态方法中的局部变量?
【问题讨论】:
标签: java dependency-injection cdi jboss-weld weld
如何以编程方式将 Java CDI 1.1+ 托管 bean 注入静态方法中的局部变量?
【问题讨论】:
标签: java dependency-injection cdi jboss-weld weld
注入类C的实例:
javax.enterprise.inject.spi.CDI.current().select(C.class).get()
这在 CDI 1.1+ 中可用
【讨论】:
例如使用此实用程序class。您基本上必须获得 BeanManager 的实例,然后从中获取您想要的 bean(想象一下 JNDI 查找之类的东西)。
更新
您还可以使用 CDI 1.1 中提供的 CDI 实用程序类
SomeBean bean = CDI.current().select(SomeBean.class).get();
更新 2
在 CDI 2.0 中,您必须使用 BeanManager 类以编程方式获取 bean 实例。
【讨论】:
@BRS
import javax.enterprise.inject.spi.CDI;
...
IObject iObject = CDI.current().select(IObject.class, new NamedAnnotation("iObject")).get();
与:
import javax.enterprise.util.AnnotationLiteral;
public class NamedAnnotation extends AnnotationLiteral<Named> implements Named {
private final String value;
public NamedAnnotation(final String value) {
this.value = value;
}
public String value() {
return value;
}
}
【讨论】:
NamedAnnotation 可以用于任何@Named bean,而不仅仅是IObjects。 ProgrammaticBeanLookup 比NamedAnnotation 需要更多的代码,但只能用于Class 或@Named String,而CDI 路由可以接受其他注释和/或TypeLiteral。 ProgrammaticBeanLookup 还要求 JNDI 类位于类路径中,如果不是,则手动填充非最终静态变量。此外,BeanManager 不能保证是线程安全的,因此ProgrammaticBeanLookup 可能存在线程问题。
CDI 用法包装在帮助方法中,例如<T> T getNamedBean(Class<T> clazz, String name)
@Petr Mensik 建议的链接非常有用。我在示例中使用了相同的代码。
这是一种在实例方法/静态方法中获取类实例的方法。为接口编写代码总是比在方法中使用硬编码的类名更好。
@Named(value = "iObject ")
@RequestScoped
class IObjectImpl implements IObject {.....}
//And in your method
IObject iObject = (IObject) ProgrammaticBeanLookup.lookup("iObject");
.........
//Invoke methods defined in the interface
当您有一个应用程序范围的对象,该对象的方法需要一个可能随时间变化的类的实例时,这种对 bean 的编程查找非常有用。因此,为了松耦合,最好提取接口并使用程序化 bean 查找。
【讨论】:
CDI 方法一起使用,它提供比ProgrammaticBeanLookup 更通用和类型安全的查找
你应该包括限定词:
List<Annotation> qualifierList = new ArrayList();
for (Annotation annotation: C.class.getAnnotations()) {
if (annotation.annotationType().isAnnotationPresent(Qualifier.class)) {
qualifierList.add(annotation);
}
}
javax.enterprise.inject.spi.CDI.current()
.select(C.class, qualifierList.toArray(new Annotation[qualifierList.size()])
.get()
【讨论】:
【讨论】: