How do I force usage of a CDI producer method?

2.4k views Asked by At

Part of my problem here is using the proper vocabulary, so I apologize in advance for what might be a simple matter of terminology.

Suppose I have a Person interface, and a PersonBean class that implements that interface.

Suppose further I have a producer method somewhere (annotated @Produces) that returns a Person. Internally it returns a new PersonBean, but that's neither here nor there.

Finally, suppose I have another CDI bean somewhere with an injection point defined like this:

@Inject
private Person person;

Assuming I have all my beans.xml files in place etc. and have bootstrapped Weld or another CDI-1.0-compliant environment, as this all stands I will get an ambiguous definition error. This makes sense: Weld will find my PersonBean as a candidate for injection (it could just call the constructor) and will find the output of my producer method as a candidate for injection.

What I'd like to do is somehow force the production of Person instances in this application to always route through the producer method.

I understand I could invent some qualifier somewhere and make the producer method produce Person instances that are qualified by that qualifier. If I do that, and change my injection point to include the qualifier, then obviously there's only one source of these qualified injectables (namely my producer method), so voila, problem solved.

But suppose I don't want to invent some bogus qualifier. (I'm not saying this is the case; just trying to more deeply understand the issues.) What are my options? Do I have any? I suppose I could put @Typed(Object.class) on the PersonBean to make it so that it was not seen as a Person by CDI....

Any ideas welcomed, including pointers to documentation, or better ways to understand this. Thanks.

3

There are 3 answers

0
Laird Nelson On BEST ANSWER

From digesting several different answers here and elsewhere, the solution I've adopted is to use the @Typed annotation with a value of Object.class on my bean. This means that it will only be eligible to be injected into fields that are declared like this:

@Inject
private Object something;

...which thankfully prove to be pretty much nonexistent. :-)

3
Jan Groth On

What I'd like to do is somehow force the production of Person instances in this application to always route through the producer method.

Seam solder has a solution for this.

I'm not 100% sure how this will develop with the merge of Seam 3 and Deltaspike (the page is so 90s, but the content rocks :-), but putting Solder in your classpath is certainly a safe bet.

Oh, and as far as I know a comparable mechanism made it into the CDI 1.1 spec.

0
Justin On

Annotate you PersonBean as @Alternative then it will use the producer method.