Reputation: 3583
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?
CDI has a Provider
interface which I can use to create the cars:
@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?
Upvotes: 15
Views: 16252
Reputation: 2858
You could use qualifiers with your @Produces
annotations:
@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;
Upvotes: 3
Reputation: 321
Just use javax.enterprise.inject.Instance
interface instead.
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 ...
}
}
Upvotes: 10
Reputation: 19563
My favorite model for programmatic lookup is to use CDI.current().select().get()
.
Demonstrated here.
The servlet has a dependency on two CDI beans, one request scoped and the other application scoped:
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.
Examine the code and you will notice that the code is fully equivalent with what you would get using @Inject MyBean myBean;
.
Upvotes: 10
Reputation: 5378
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.
Upvotes: 0