首页 > 解决方案 > 使用 CDI Produces 获取注入的对象

问题描述

我有一个包含注入字段(蔬菜)的类(OmeletteMaker)。我想写一个生产者来实例化这个类的注入对象。如果我使用'new',结果将不会使用注入。如果我尝试使用 WeldContainer,则会出现异常,因为 OmeletteMaker 是 @Alternative。有没有第三种方法可以实现这一目标?

这是我的代码:

@Alternative
public class OmeletteMaker implements EggMaker {
    @Inject
    Vegetable vegetable;

    @Override
    public String toString() {
        return "Omelette: " + vegetable;
    }
}

注射用蔬菜:

public class Tomato implements Vegetable {
    @Override
    public String toString() {
        return "Tomato";
    }

}

主文件

public class CafeteriaMainApp {
    public static WeldContainer container = new Weld().initialize();
    public static void main(String[] args) {

        Restaurant restaurant = (Restaurant) container.instance().select(Restaurant.class).get();
        System.out.println(restaurant);

    }

    @Produces
    public EggMaker eggMakerGenerator() {
         return new OmeletteMaker();
    }


}

我得到的结果是“餐厅:煎蛋卷:null”,而我想得到“餐厅:煎蛋卷:番茄”

标签: dependency-injectioncdi

解决方案


如果您自己提供 OmeletteMaker,则其字段将不会由 CDI 容器注入。要使用@Alternative,不要忘记在 中指定它beans.xml并让容器实例化 EggMaker 实例:

<alternatives>
    <class>your.package.path.OmeletteMaker</class>
</alternatives>

如果您只想使用 Producer 方法来实现这一点,那么我的回答可能不合适。我认为这是不可能的(使用标准 CDI)。文档说:生产者方法提供了一种注入非 bean 对象、值可能在运行时变化的对象以及需要自定义初始化的对象的方法。

感谢 Kukeltje 在评论中指出另一个 CDI 问题:使用像 Deltaspike 这样的 CDI 扩展,可以将字段注入到使用创建的对象中new,只需使用BeanProvider#injectFileds. 我自己对此进行了测试:

    @Produces
    public EggMaker eggMakerProducer() {
        EggMaker eggMaker =  new OmeletteMaker();
        BeanProvider.injectFields(eggMaker);
        return eggMaker;
    }

推荐阅读