使用 CDI Produces 获取注入对象

Getting an injected object using CDI Produces

我有一个 class (OmeletteMaker),其中包含一个注入字段(蔬菜)。我想编写一个生产者来实例化此 class 的注入对象。如果我使用'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();
    }


}

我得到的结果是"Restaurant: Omelette: null",而我想得到"Restaurant: Omelette: Tomato"

如果你自己提供OmeletteMaker,它的字段不会被CDI容器注入。要使用@Alternative,别忘了在beans.xml中指定,让容器实例化EggMaker实例:

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

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

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

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