I have a CDI producer method which – depending on some conditions not relevant to this example – creates objects of different types:
public class TestProducer {
@Produces @TestQualifier
public Object create(InjectionPoint ip) {
if(something) {
return "a String";
} else {
return Integer.valueOf(42);
}
}
but when using this producer, I always get an error in the followin situation:
@Named("test")
public class TestComponent {
...
@Inject public void setA(@TestQualifier String stringValue) {
...
@Inject public void setB(@TestQualifier Integer integerValue) {
It only works when the create method of the producer has the expected type in the method signature:
public class TestProducer {
@Produces @SpringBean
public String create(InjectionPoint ip) {
Now the String get’s injected correctly, but I have no way to also generate an integer from the producer method. But this is exactly what I want to avoid, since the producer itself should be completely generic.
Am I doing something wrong or is there no way to achieve the behaviour I want?
All CDI documentation makes it clear that CDI does typesafe dependency injection – and it is an exalted property of CDI. IMHO, what you are trying to do is just what CDI tries to avoid. You want the container to cast
Objectto each type and CDI does not work that way.The injections points
stringValueandintegerValuecan only receive a bean which hasjava.lang.Stringandjava.lang.Integerin its list of bean types respectively.java.lang.Objectdoes not satisfy this criterion.I have two suggestions. First, since you have two or more injection points of different types, create two or more producer methods for that types:
It works if the
somethingcondition is just to check the type of the injection point (what I am betting is the case).However, if the
somethingcondition does decide the type using other criteria than the type of the injection point, I’d suggestion to do the “dirty job” yourself: inject the returned value in anObject-typed injection point and does the cast manually:The main point is that, unlike some other DI frameworks, CDI does not work against the Java type system – on the contrary, it heavily uses it. Do not try to fight against it but use this aspect of CDI in your favor 🙂