java 如何在 CDI 中动态创建实例
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15067650/
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
How to create instances on the fly in CDI
提问by palto
Let's assume I have a Car class. In my code I want to create 10 cars. Car class has some @Inject annotated dependencies. What would be the best approach to do this?
假设我有一个 Car 类。在我的代码中,我想创建 10 辆车。Car 类有一些 @Inject 注释的依赖项。这样做的最佳方法是什么?
CDI has a Provider interface which I can use to create the cars:
CDI 有一个 Provider 接口,我可以用它来创建汽车:
@Inject Provider<Car> carProvider;
public void businessMethod(){
Car car = carProvider.get();
}
Unfortunately that doesn't work if I don't have a CarFactory that has a method with @Produces annotation which creates the car. As much as it reflects real world that I cannot create cars without a factory, I'd rather not write factories for everything. I just want the CDI container to create my car just like any other bean. How do you recommend I create those Cars?
不幸的是,如果我没有一个 CarFactory 有一个带有 @Produces 注释的方法来创建汽车,这将不起作用。尽管它反映了现实世界,如果没有工厂,我就无法制造汽车,但我宁愿不为一切编写工厂。我只是想让 CDI 容器像任何其他 bean 一样创建我的汽车。你如何推荐我创造这些汽车?
采纳答案by temaleva
Just use javax.enterprise.inject.Instance interface instead.
只需使用 javax.enterprise.inject.Instance 接口代替。
Like this:
像这样:
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 ...
}
}
回答by Martin Andersson
My favorite model for programmatic lookup is to use CDI.current().select().get()
.
我最喜欢的程序化查找模型是使用CDI.current().select().get()
.
Demonstrated here.
在这里展示。
The servlet has a dependency on two CDI beans, one request scoped and the other application scoped:
servlet 依赖于两个 CDI bean,一个是请求范围的,另一个是应用程序范围的:
private final RequestScopedBean requestScoped
= CDI.current().select(RequestScopedBean.class).get();
private final ApplicationScopedBean applicationScoped
= CDI.current().select(ApplicationScopedBean.class).get();
The test class that uses this servlet can be found here.
可以在此处找到使用此 servlet 的测试类。
Examine the code and you will notice that the code is fully equivalent with what you would get using @Inject MyBean myBean;
.
检查代码,您会注意到该代码与您将使用的内容完全等效@Inject MyBean myBean;
。
回答by FibreFoX
You could use qualifiers with your @Produces annotations:
您可以在 @Produces 注释中使用限定符:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE, ElementType.FIELD, ElementType.PARAMETER})
public @interface MyCars {
}
sample-producer-method:
样品生产者方法:
@Produces
@MyCars
public Car getNewCar(@New Car car){
return car;
}
usage:
用法:
@Inject
@MyCars
private Provider<Car> carProvider;
回答by LightGuard
Another way to do it would be to simple not give Car any CDI scope, that makes it dependent and you'll get a new instance each time it's injected and those instances won't be destroyed until the containing instance is destroyed.
另一种方法是简单地不给 Car 任何 CDI 范围,这使其具有依赖性,并且每次注入时您都会获得一个新实例,并且在包含实例被销毁之前这些实例不会被销毁。