如何以编程方式将 Java CDI 托管 bean 注入(静态)方法中的局部变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24798529/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:53:53  来源:igfitidea点击:

How to programmatically inject a Java CDI managed bean into a local variable in a (static) method

javadependency-injectioncdijboss-weldweld

提问by XDR

How can I programmatically inject a Java CDI 1.1+ managed bean into a local variable in a static method?

如何以编程方式将 Java CDI 1.1+ 托管 bean 注入静态方法中的局部变量?

采纳答案by XDR

To inject an instance of class C:

注入一个类的实例C

javax.enterprise.inject.spi.CDI.current().select(C.class).get()

This is available in CDI 1.1+

这在 CDI 1.1+ 中可用

回答by Petr Mensik

Use for instance this utility class. You basically have to obtain instance of BeanManagerand than grab the bean you want from it (imagine something like JNDI lookup).

例如使用这个实用程序。您基本上必须获取实例,BeanManager然后从中获取所需的 bean(想象一下 JNDI 查找之类的东西)。

Update

更新

You could also use CDIutility class offered in CDI 1.1

您还可以使用CDI 1.1 中提供的CDI实用程序类

SomeBean bean = CDI.current().select(SomeBean.class).get();

Update 2

更新 2

In CDI 2.0 you have to use BeanManagerclass for obtaining bean instances programatically.

在 CDI 2.0 中,您必须使用BeanManager类以编程方式获取 bean 实例。

回答by phoenix

The link suggested by @Petr Mensik is very useful. I am using the same code in my example.

@Petr Mensik 建议的链接非常有用。我在我的例子中使用了相同的代码。

Here is a way to get an instance of the class in instance methods/static methods. It is always better to code for interfaces instead of using the class name hard coded in the methods.

这是一种在实例方法/静态方法中获取类实例的方法。为接口编码总是更好,而不是在方法中使用硬编码的类名。

@Named(value = "iObject ")
@RequestScoped
class IObjectImpl  implements IObject  {.....}

//And in your method

IObject iObject = (IObject) ProgrammaticBeanLookup.lookup("iObject");
.........
//Invoke methods defined in the interface

This programmatic look up of beans can be quite useful when you have an application scoped object with method that requires an instance of a class that may change over time. So, it is always better to extract the interface and use programmatic bean look up for the sake of loose coupling.

当您有一个应用程序范围的对象和方法需要一个可能会随着时间改变的类的实例时,这种对 bean 的编程查找可能非常有用。因此,为了松耦合,最好提取接口并使用程序化 bean 查找。

回答by XDR

@BRS

@BRS

import javax.enterprise.inject.spi.CDI;

...

IObject iObject = CDI.current().select(IObject.class, new NamedAnnotation("iObject")).get();

With:

和:

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;
    }
}

回答by jpangamarca

  • You could define a parameter with the type of the bean interface in your static method, and pass an appropriate implementation reference. That would make it more unit-testing friendly.
  • If you're using Apache Deltaspike, you can use BeanProvider#getContextualReference. It's easier than getting a javax.enterprise.inject.Instance, but, beware of dependent beans (see javadoc)!
  • 您可以在静态方法中使用 bean 接口的类型定义一个参数,并传递适当的实现引用。这将使其对单元测试更加友好。
  • 如果您使用Apache Deltaspike,则可以使用BeanProvider#getContextualReference。它比获取 javax.enterprise.inject.Instance 更容易,但是,要注意依赖 bean(请参阅 javadoc)!

回答by Manuel Baena García

You should include qualifiers:

您应该包括限定词:

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()