繁体   English   中英

如何使用CDI进行方法参数注入?

[英]How to use CDI for method parameter injection?

是否可以使用CDI将参数注入方法调用? 预期的行为类似于现场注入。 查找首选生产者并使用产品。

我想做的是:

public void foo(@Inject Bar bar){
  //do stuff
} 

或者这个(使用较少混淆的sytax):

public void foo(){
  @Inject 
  Bar bar;
  //do stuff
} 

在这两种情况下,此语法都是非法的 还有其他选择吗? 如果不是 - 如果有可能,出于某种原因,这会是一个坏主意吗?

谢谢

编辑 - 我可能已经使我的要求不够清楚 - 我希望能够直接调用该方法,将bar变量的初始化保留到容器中。 JörnHorstmann和Perception的回答表明这是不可能的。

当bean被容器实例化时,将为bean处理注入点,这限制了方法级注入的用例数。 规范的当前版本识别以下类型的方法注入:

初始化方法注入

public class MyBean {
    private Processor processor;

    @Inject
    public void setProcessor(final Processor processor) {
        this.processor = processor;
    }
}

当注入MyBean的实例时,也会通过它的setter方法注入处理器实例。

事件观察者方法

public class MyEventHandler {
    public void processSomeEvent(@Observes final SomeEvent event) {
    }
}

事件实例直接注入到事件处理方法中(但不是使用@Inject注释)

制片人方法

public class ProcessorFactory {
    @Produces public Processor getProcessor(@Inject final Gateway gateway) {
        // ...
    }
}

生成器方法的参数自动注入。

如果您真正想要的不是作为方法的参数(应该由调用者提供),而是每次调用方法并完全构造和注入时正确初始化CDI bean的实例,然后检查

javax.inject.Provider<T>

基本上,首先向该类注入提供者

@Inject Provider<YourBean> yourBeanProvider;

然后,在该方法中,获取一个新实例

YourBean bean = yourBeanProvider.get();

希望这可以帮助 :)

当我最初对这个主题进行搜索时出现了这个问题,并且我已经了解到随着CDI 1.1的发布(包含在JavaEE 7规范中),现在有一种方法可以实际执行OP所需的部分内容。 你还是做不到

public void foo(@Inject Bar bar){
   //do stuff
}

但你可以“注入”一个局部变量,虽然你不使用@Inject ,而是以编程方式查找注入的实例,如下所示:

public void foo() {
    Instance<Bar> instance = CDI.current().select(Bar.class);
    Bar bar = instance.get();
    CDI.current().destroy(instance);
    // do stuff with bar here
}

请注意, select()方法可以select()使用您可能需要提供的任何限定符注释。 祝你好运获得java.lang.annotation.Annotation实例。 迭代您的Instance<Bar>可能更容易找到您想要的那个。

我被告知你需要像我上面所做的那样销毁Instance<Bar> ,并且可以从经验中验证上述代码的工作原理; 但是,我不能发誓你需要摧毁它。

CDI的这一特性称为“初始化方法”。 语法与您的代码的不同之处在于整个方法都使用@Inject注释,方法参数可以进一步由限定符注释以选择特定的bean。 JSR 299的 3.9节显示了以下示例,其中@Selected是一个限定符,如果只有一个bean实现,则可以省略该限定符。

@Inject
void setProduct(@Selected Product product) {
    this.product = product;
}

请注意

应用程序可以直接调用初始化方法,但是容器不会将任何参数传递给方法。

您可以在方法中使用BeanManager API来获取上下文引用,或者根据您可以注入的最终目标

Instance<Bar>

在方法之外并在方法中使用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM