Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I force usage of a CDI producer method?

Tags:

cdi

jsr299

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.

like image 828
Laird Nelson Avatar asked Jun 06 '12 16:06

Laird Nelson


2 Answers

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

like image 126
Justin Avatar answered Sep 19 '22 05:09

Justin


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. :-)

like image 28
Laird Nelson Avatar answered Sep 18 '22 05:09

Laird Nelson