如何在CDI中动态创建实例

时间:2013-02-25 13:04:16

标签: java java-ee-6 cdi

我们假设我有一个Car类。在我的代码中,我想创建10辆汽车。 Car类有一些@Inject注释依赖项。这样做的最佳方法是什么?

CDI有一个我可以用来创建汽车的供应商界面:

@Inject Provider<Car> carProvider;
public void businessMethod(){
    Car car = carProvider.get();
}

不幸的是,如果我没有CarFactory,它有一个带有@Produces注释的方法来创建汽车,那就不行了。尽管它反映了现实世界我无法在没有工厂的情况下制造汽车,但我宁愿不为所有东西编写工厂。我只是希望CDI容器像任何其他bean一样创建我的汽车。你怎么建议我创造这些汽车?

4 个答案:

答案 0 :(得分:9)

请改用javax.enterprise.inject.Instance接口。

像这样:

public class Bean {

    private Instance<Car> carInstances;

    @Inject
    Bean(@Any Instance<Car> carInstances){
        this.carInstances = carInstances;
    }

    public void use(){
        Car newCar = carInstances.get();
        // Do stuff with car ...
    }

}

答案 1 :(得分:7)

我最喜欢的程序化查找模型是使用CDI.current().select().get()

展示here

servlet依赖于两个CDI bean,一个请求作用域,另一个作用域作用域:

private final RequestScopedBean requestScoped
            = CDI.current().select(RequestScopedBean.class).get();

private final ApplicationScopedBean applicationScoped
            = CDI.current().select(ApplicationScopedBean.class).get();

可以找到使用此servlet的测试类here

检查代码,您会发现代码完全等同于使用@Inject MyBean myBean;所获得的代码。

答案 2 :(得分:3)

您可以在@Produces注释中使用限定符:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
public @interface MyCars {
}

采样生产者方法:

@Produces
@MyCars
public Car getNewCar(@New Car car){
    return car;
}

用法:

@Inject
@MyCars
private Provider<Car> carProvider;

答案 3 :(得分:0)

另一种方法是简单地不给Car任何CDI范围,这使得它依赖于每次注入时你将得到一个新实例,并且在包含实例被销毁之前不会销毁这些实例。